# mob_dev v0.7.21 - Table of Contents

> Development tooling for the Mob mobile framework

## Pages

- [mob_dev](readme.md)
- [Changelog](changelog.md)
- [Building OTP Release Tarballs](build_release.md)

- Guides
  - [Static NIFs (C, Rust, Zig, Python)](nifs.md)
  - [Security scanning](security_scan.md)
  - [Slim Release (bundle size)](slim_release.md)
  - [Publishing to TestFlight (iOS)](publishing_to_testflight.md)
  - [Publishing to Google Play (Android)](publishing_to_google_play.md)
  - [Embedded CPython (iOS)](python_embedding.md)

## Modules

- Server
  - [MobDev.Server.DashboardLive](MobDev.Server.DashboardLive.md)
  - [MobDev.Server.DevicePoller](MobDev.Server.DevicePoller.md): Polls adb and simctl every 2 seconds, broadcasting device state changes via PubSub.

  - [MobDev.Server.ElixirLogBuffer](MobDev.Server.ElixirLogBuffer.md): Holds the last 200 server-side Elixir log lines in memory so the dashboard
can restore them on reconnect. Fed by `MobDev.Server.ElixirLogger`.

  - [MobDev.Server.ElixirLogger](MobDev.Server.ElixirLogger.md): OTP logger handler that captures Elixir `Logger` output and forwards it
to the Mob dev server dashboard.
  - [MobDev.Server.Endpoint](MobDev.Server.Endpoint.md)
  - [MobDev.Server.Layouts](MobDev.Server.Layouts.md)
  - [MobDev.Server.LogBuffer](MobDev.Server.LogBuffer.md): Holds the last 500 log lines in memory so the LiveView can restore them on
reconnect without losing context from before a crash or page refresh.

  - [MobDev.Server.LogFilter](MobDev.Server.LogFilter.md): Pure filter functions for the log stream. Extracted here so they can be
unit-tested without mounting a LiveView.

  - [MobDev.Server.LogStreamer](MobDev.Server.LogStreamer.md): Streams logcat from connected Android devices and iOS simulator console,
broadcasting parsed lines via PubSub.
  - [MobDev.Server.LogStreamerSupervisor](MobDev.Server.LogStreamerSupervisor.md): Isolated supervisor for LogStreamer.
  - [MobDev.Server.Router](MobDev.Server.Router.md)
  - [MobDev.Server.WatchWorker](MobDev.Server.WatchWorker.md): GenServer that runs the mob.watch loop inside the mob.server process.

- Internals
  - [MobDev.Adopt.Generator](MobDev.Adopt.Generator.md): EEx-template assigns, native-tree template/static roots, dep
resolution, and Pythonx wiring for `mix mob.adopt`.
  - [MobDev.Adopt.Patcher](MobDev.Adopt.Patcher.md): Pure helpers for the `mix mob.adopt` Elixir-source patches and
content generators: the LiveView bridge patches (`assets/js/app.js`
MobHook + `root.html.heex` bridge div), the `mix.exs` dep injection,
and the generated `mob_screen.ex` / `mob_app.ex` / `mob.exs` /
`src/<app>.erl` contents.
  - [MobDev.AppConfig](MobDev.AppConfig.md): Ships the project's application config to the device as the generated
Erlang module `mob_app_config`.
  - [MobDev.AppLifecycleHooks](MobDev.AppLifecycleHooks.md): Detects an Android app that predates the `Mob.Device` `:app` lifecycle hooks.
  - [MobDev.Attest](MobDev.Attest.md): Prove that the code running on a device is the code you just pushed.
  - [MobDev.Bench.DeviceObserver](MobDev.Bench.DeviceObserver.md): Subscribes to `Mob.Device` events on the running app over Erlang
distribution and tracks ground-truth screen/app state for the bench.
  - [MobDev.Bench.Logger](MobDev.Bench.Logger.md): Append-only CSV log of bench probe snapshots.
  - [MobDev.Bench.Preflight](MobDev.Bench.Preflight.md): Pre-run checklist for the iOS battery bench.
  - [MobDev.Bench.Probe](MobDev.Bench.Probe.md): Multi-source state probe for the battery bench.
  - [MobDev.Bench.Reconnector](MobDev.Bench.Reconnector.md): Auto-reconnect logic for the bench's BEAM dist connection.
  - [MobDev.Bench.Summary](MobDev.Bench.Summary.md): Post-run analysis of a bench CSV log.
  - [MobDev.Connector](MobDev.Connector.md): Orchestrates device discovery, tunnel setup, app restart, and node connection.
  - [MobDev.Deployer](MobDev.Deployer.md): Pushes compiled BEAM files from the active Mix build path to connected devices.
  - [MobDev.Device](MobDev.Device.md): Represents a connected or available device (physical or emulator/simulator).

  - [MobDev.DeviceLeases](MobDev.DeviceLeases.md): agent-device device claims, read as leases, so a task that picks devices on
its own leaves alone a device another agent has claimed (MOB-330).
  - [MobDev.Differential](MobDev.Differential.md): Drive `Mob.Differential.compare/3` against two live device nodes.
  - [MobDev.Discovery.Android](MobDev.Discovery.Android.md): Discovers Android devices and emulators via adb.
  - [MobDev.Discovery.IOS](MobDev.Discovery.IOS.md): Discovers iOS simulators via xcrun simctl.
  - [MobDev.DistCookie](MobDev.DistCookie.md): The private distribution cookie for a project's development builds.
  - [MobDev.Emulators](MobDev.Emulators.md): List, start, and stop Android emulators (AVDs) and iOS simulators.
  - [MobDev.Enable](MobDev.Enable.md): Pure helpers for `mix mob.enable` — extracted for testability.
  - [MobDev.Enable.Igniter](MobDev.Enable.Igniter.md): Igniter-aware feature handlers for `mix mob.enable`.
  - [MobDev.ErrorView](MobDev.ErrorView.md)
  - [MobDev.GooglePlay](MobDev.GooglePlay.md): Google Play Developer API client for uploading Android App Bundles.
  - [MobDev.GooglePlay.CloudSetup](MobDev.GooglePlay.CloudSetup.md): Google Cloud REST API operations for the Play Store setup wizard.
  - [MobDev.GooglePlay.OAuth](MobDev.GooglePlay.OAuth.md): OAuth2 browser-based authorization for Google APIs.
  - [MobDev.GooglePlay.PlaySetup](MobDev.GooglePlay.PlaySetup.md): Google Play Developer API operations for granting service account access.
  - [MobDev.GooglePlay.SetupWizard](MobDev.GooglePlay.SetupWizard.md): Interactive wizard for the Google Play one-time setup.
  - [MobDev.HotPush](MobDev.HotPush.md): Connects to already-running device nodes and hot-pushes BEAM modules via RPC.
  - [MobDev.IOSInstalls](MobDev.IOSInstalls.md): A record of which apps `mob_dev` has installed on which physical iOS device.
  - [MobDev.IconGenerator](MobDev.IconGenerator.md): Generates app icons for Android and iOS from either a random robot avatar
(using Avatarz) or a provided source image (using Image).
  - [MobDev.IosLayoutPlist](MobDev.IosLayoutPlist.md): The Info.plist keys that decide where an iOS app runs and how it may lay
out: `UIDeviceFamily` (iPhone `1`, iPad `2`), `UISupportedInterfaceOrientations`
(iPhone), `UISupportedInterfaceOrientations~ipad`, and `UIRequiresFullScreen`.
  - [MobDev.MLXDownloader](MobDev.MLXDownloader.md): Downloads and caches pre-built Apple MLX + EMLX NIF static archives so
iOS Mob apps can ship `EMLX.Backend` as an Nx backend without
cross-compiling MLX themselves.
  - [MobDev.MobDirCheck](MobDev.MobDirCheck.md): Detects a `mob.exs` `mob_dir` that names a different mob than the `:mob`
dependency.
  - [MobDev.MobExs](MobDev.MobExs.md): Text edits to a project's committed `mob.exs` and its gitignored
`mob.local.exs` override file.
  - [MobDev.MobNifTable](MobDev.MobNifTable.md): The `-nifs` difference between two mob checkouts' `src/mob_nif.erl`.
  - [MobDev.Mutate](MobDev.Mutate.md): Mutation testing: change the production code, and see whether the suite
notices.
  - [MobDev.NativeBuild](MobDev.NativeBuild.md): Builds native binaries (APK for Android, .app bundle for iOS simulator)
for the current Mob project.
  - [MobDev.NdkVersion](MobDev.NdkVersion.md): Single source of truth for the Android NDK version Mob's bundled OTP
runtime was cross-compiled against.
  - [MobDev.Network](MobDev.Network.md): Network utilities for mob_dev.
  - [MobDev.NxEigenNif](MobDev.NxEigenNif.md): Cross-compiles the `nx_eigen` C++ NIF (Eigen-backed Nx backend) for one
Android or iOS target ABI and archives the result as `libnx_eigen.a`.
The archive gets static-linked into the user app's main native binary
alongside `crypto.a`, `libemlx.a`, and any other static NIFs.
  - [MobDev.NxEigenNif.Target](MobDev.NxEigenNif.Target.md): Per-target description: arch path layout, toolchain factory, extra CXXFLAGS, expected nm symbol.
  - [MobDev.OtpAssetBundle](MobDev.OtpAssetBundle.md): Builds the `assets/otp.zip` that release-mode Android Mob apps extract on
first launch.
  - [MobDev.OtpAudit](MobDev.OtpAudit.md): Reachability analysis for the bundled OTP runtime tree of a Mob app.
  - [MobDev.OtpAudit.Slim](MobDev.OtpAudit.Slim.md): In-place strip pass for the per-app OTP bundle, called by
`MobDev.NativeBuild` when `MOB_SLIM=1`. Was an inline ~100-line
`defp` in `native_build.ex`; extracted here so it's testable and
has a place for per-app override hooks to live.
  - [MobDev.OtpDownloader](MobDev.OtpDownloader.md): Downloads and caches pre-built OTP releases from GitHub for Android and iOS simulator.
  - [MobDev.OtpRequiredApps](MobDev.OtpRequiredApps.md): The applications a Mob app needs at runtime, so no slim pass strips one.
  - [MobDev.OtpTrace](MobDev.OtpTrace.md): Runtime call-tracing utility. Wraps `:erlang.trace_pattern/3` and
`:erlang.trace/3` to capture the set of `{module, function, arity}`
actually called during a function's execution.
  - [MobDev.OtpTrace.Harness](MobDev.OtpTrace.Harness.md): Characterization harness: a curated set of Elixir features exercised
in tight blocks. Designed to be wrapped in `MobDev.OtpTrace.capture/1`
to record the runtime modules touched by typical Elixir code.
  - [MobDev.Paths](MobDev.Paths.md): Resolution helpers for paths Mob writes to outside the project tree.
  - [MobDev.Plugin](MobDev.Plugin.md): Compile-time host-config surface for code-generated plugins.
  - [MobDev.Plugin.AndroidBootstrap](MobDev.Plugin.AndroidBootstrap.md): Generates opt-in Android `ui_components` registrations for
`io.mob.plugin.MobPluginBootstrap`.
  - [MobDev.Plugin.Assets](MobDev.Plugin.Assets.md): Pure planners for the tier-3 build-time file merges — migrations, fonts, and
images — that `native_build` copies into the host app at build.
  - [MobDev.Plugin.Audit](MobDev.Plugin.Audit.md): Static-analysis pass over a plugin's source tree.
  - [MobDev.Plugin.CppArchive](MobDev.Plugin.CppArchive.md): Cross-compiles a plugin's `lang: :cpp_archive` NIF — a set of C/C++ sources —
into `lib<module>.a` for one target ABI, and verifies the NIF-init symbol is
present. The archive is then static-linked into the app's single signed native
binary (same slot as `crypto.a` / `libnx_eigen.a`).
  - [MobDev.Plugin.Crypto](MobDev.Plugin.Crypto.md): Ed25519 sign/verify primitives + canonical-term encoding for plugin signing.
  - [MobDev.Plugin.IOSBootstrap](MobDev.Plugin.IOSBootstrap.md): Code-generates the iOS plugin bootstrap Swift source from the activated
plugins' `:ui_components` declarations.
  - [MobDev.Plugin.ManagedBlock](MobDev.Plugin.ManagedBlock.md): Reversible insertion of plugin-contributed fragments into host-owned build
files (`AndroidManifest.xml`, `build.gradle`). `MobDev.UrlSchemes` uses the
same fencing for the `mob.exs` `url_schemes` intent filter.
  - [MobDev.Plugin.Manifest](MobDev.Plugin.Manifest.md): Reads, validates, and classifies a plugin's `priv/mob_plugin.exs` manifest.
  - [MobDev.Plugin.Merge](MobDev.Plugin.Merge.md): Gathers the contributions of the activated plugins into combined lists the
build pipeline consumes.
  - [MobDev.Plugin.NifActivation](MobDev.Plugin.NifActivation.md): Warnings for the two ways a plugin's NIF silently misses the installed app
(MOB-281).
  - [MobDev.Plugin.Prebuilt](MobDev.Plugin.Prebuilt.md): Fetches the prebuilt bundle a `lang: :cpp_archive` plugin NIF declares under
`:prebuilt`, and resolves the headers and static libraries it contributes.
  - [MobDev.Plugin.PrivateKeyStore](MobDev.Plugin.PrivateKeyStore.md): Author-side storage for the per-plugin Ed25519 private key.
  - [MobDev.Plugin.Report](MobDev.Plugin.Report.md): Pure transforms behind `mix mob.plugins`: turn discovered deps + the
activation list into report rows, and render them as a table.
  - [MobDev.Plugin.RuntimeManifest](MobDev.Plugin.RuntimeManifest.md): Builds the host's **runtime plugin manifest** — the device-readable record of
the activated plugins' tier-3/4 contributions.
  - [MobDev.Plugin.Scaffold](MobDev.Plugin.Scaffold.md): Pure templates + name conversions behind `mix mob.new_plugin`.
  - [MobDev.Plugin.SelfTest](MobDev.Plugin.SelfTest.md): Runs every activated plugin's `Mob.Plugin.SelfTest` on a device.
  - [MobDev.Plugin.Sign](MobDev.Plugin.Sign.md): Author-side signing workflow for mob plugins.
  - [MobDev.Plugin.SignatureGate](MobDev.Plugin.SignatureGate.md): Host-side build-time gate: runs `Verify.verify_plugin/2` + the
`TrustStore` check across every activated plugin and refuses the
build on any failure.
  - [MobDev.Plugin.TrustStore](MobDev.Plugin.TrustStore.md): Reads + writes the `config :mob, :trusted_plugins, %{...}` entry in `mob.exs`.
  - [MobDev.Plugin.Validator](MobDev.Plugin.Validator.md): Validates plugin manifests, in two stages (see [`MOB_PLUGINS.md`](https://github.com/GenericJam/mob/blob/master/MOB_PLUGINS.md)).
  - [MobDev.Plugin.Verify](MobDev.Plugin.Verify.md): Host-side signature verification for activated mob plugins.
  - [MobDev.PythonAndroidSupport](MobDev.PythonAndroidSupport.md): Downloads and caches a Chaquopy CPython distribution so Android builds
can embed Python.
  - [MobDev.PythonAppleSupport](MobDev.PythonAppleSupport.md): Downloads and caches BeeWare's Python-Apple-support bundle so iOS
builds can embed CPython.
  - [MobDev.QR](MobDev.QR.md): Renders QR codes in the terminal using Unicode half-block characters.
Uses eqrcode for matrix generation.

  - [MobDev.Release](MobDev.Release.md): Build a signed, App-Store-ready iOS `.ipa` for the current Mob project.
  - [MobDev.Release.Errors](MobDev.Release.Errors.md): Typed error tags used across the `MobDev.Release.*` modules.
  - [MobDev.Release.Helpers](MobDev.Release.Helpers.md): Replaces the two `scripts/release/_lib.sh` files. Pure functions where
possible; side-effectful ones are narrow + testable via tmpdir fixtures.
  - [MobDev.Release.OTP](MobDev.Release.OTP.md): Replaces `scripts/release/xcompile_*.sh` × 3 + the misplaced
`scripts/release/openssl/_build_otp_android_arm64.sh`. Cross-compiles
the Erlang OTP runtime for one of four target ABIs and stages the
install tree at a release root.
  - [MobDev.Release.OTP.Target](MobDev.Release.OTP.Target.md): Per-target OTP cross-compile description.
  - [MobDev.Release.OpenSSL](MobDev.Release.OpenSSL.md): Replaces `scripts/release/openssl/{android_arm64,android_arm32,ios_sim,
ios_device}.sh`. Cross-compiles OpenSSL 3.x for the four target
ABIs that Mob's bundled OTP tarballs link against, producing static
`libcrypto.a` + `libssl.a` + headers under a per-target `--prefix`.
  - [MobDev.Release.OpenSSL.CryptoNif](MobDev.Release.OpenSSL.CryptoNif.md): Replaces `scripts/release/openssl/build_crypto_static_*.sh` (×4).
Compiles OTP's crypto NIF C sources with `-DSTATIC_ERLANG_NIF` for one
target ABI and archives the result as `crypto.a`. Pairs with
`MobDev.Release.OpenSSL` (the OpenSSL build itself) to produce the
two `.a` files that get static-linked into the user app's main
native binary
  - [MobDev.Release.OpenSSL.CryptoNif.Target](MobDev.Release.OpenSSL.CryptoNif.Target.md): Per-target description: arch path layout, toolchain factory, extra CFLAGS, expected nm symbol.
  - [MobDev.Release.OpenSSL.Target](MobDev.Release.OpenSSL.Target.md): One cross-compile target. `env_fn` is invoked at build time so it
can read live `:code.lib_dir(:elixir)` / NDK version / etc.

  - [MobDev.Release.Publish](MobDev.Release.Publish.md): Replaces `scripts/release/publish.sh` — uploads built tarballs to a
GitHub release tagged `otp-<hash>`. The release is created if it
doesn't exist; existing assets with matching names are deleted before
upload (`gh release upload` won't replace by default).
  - [MobDev.Release.Shell](MobDev.Release.Shell.md): The I/O surface for `MobDev.Release.*` modules — every external command,
every env-var read, every filesystem inspection that crosses out of
Elixir's BEAM happens through a function declared here.
  - [MobDev.Release.Shell.System](MobDev.Release.Shell.System.md): Production implementation of `MobDev.Release.Shell` — uses the real
`System`, `File`, and OS to do work. Pure passthrough; the
intelligence is in the callers.

  - [MobDev.Release.Tarball](MobDev.Release.Tarball.md): Replaces `scripts/release/tarball_*.sh` × 4 — the staging + `tar czf`
step that produces the `otp-<target>-<hash>.tar.gz` archive
`MobDev.OtpDownloader` later fetches.
  - [MobDev.Release.Tarball.Target](MobDev.Release.Tarball.Target.md): Per-target tarball staging description.
  - [MobDev.ReleaseAndroid](MobDev.ReleaseAndroid.md): Builds the signed release AAB for a Mob Android app.
  - [MobDev.SecurityScan](MobDev.SecurityScan.md): Top-level API for `mix mob.security_scan`.
  - [MobDev.SecurityScan.BundledRuntime.Fingerprint](MobDev.SecurityScan.BundledRuntime.Fingerprint.md): Extracts versions from `~/.mob/cache/otp-*-{hash}/` and from exqlite
C sources in a project's `deps/`.
  - [MobDev.SecurityScan.BundledVersions](MobDev.SecurityScan.BundledVersions.md): Loads `priv/security/bundled_versions.exs` — the source-of-truth
manifest of what versions ship inside the OTP tarballs that
`MobDev.OtpDownloader` distributes.
  - [MobDev.SecurityScan.Diff](MobDev.SecurityScan.Diff.md): Computes the delta between the previous scan state and the
current report
  - [MobDev.SecurityScan.Finding](MobDev.SecurityScan.Finding.md): A single normalized security finding.
  - [MobDev.SecurityScan.Formatter](MobDev.SecurityScan.Formatter.md): Render a `Report` for human or machine consumers.
  - [MobDev.SecurityScan.HistoryFormatter](MobDev.SecurityScan.HistoryFormatter.md): Render a single changelog entry for `SECURITY_HISTORY.md`.
  - [MobDev.SecurityScan.Layer](MobDev.SecurityScan.Layer.md): Behaviour every scan layer implements.
  - [MobDev.SecurityScan.LayerResult](MobDev.SecurityScan.LayerResult.md): Result of running a single scan layer (Hex deps, Gradle deps,
bundled runtime, C source, etc).
  - [MobDev.SecurityScan.Layers.BundledRuntime](MobDev.SecurityScan.Layers.BundledRuntime.md): Audits the OpenSSL, ERTS, Elixir, exqlite, and SQLite versions
baked into Mob's pre-built OTP tarballs and into the project's
`deps/exqlite/c_src/sqlite3.c`.
  - [MobDev.SecurityScan.Layers.CSource](MobDev.SecurityScan.Layers.CSource.md): Static analysis of every C source file Mob actually compiles into
the app: Mob's own NIF shims (`mob/android/jni/`, `mob/ios/`), the
exqlite NIF wrapper (`deps/exqlite/c_src/sqlite3_nif.c`), and any
C the project itself ships.
  - [MobDev.SecurityScan.Layers.GradleDeps](MobDev.SecurityScan.Layers.GradleDeps.md): Audits Android dependencies via `osv-scanner` recursively over
the `android/` directory.
  - [MobDev.SecurityScan.Layers.HexDeps](MobDev.SecurityScan.Layers.HexDeps.md): Audits Hex dependencies in `mix.lock` against two complementary
advisory sources
  - [MobDev.SecurityScan.Layers.KotlinSource](MobDev.SecurityScan.Layers.KotlinSource.md): Static analysis of Kotlin/Java source under `android/app/src/main/`
using [detekt](https://detekt.dev/).
  - [MobDev.SecurityScan.Layers.SwiftDeps](MobDev.SecurityScan.Layers.SwiftDeps.md): Audits iOS dependencies via `osv-scanner` recursively over the
`ios/` directory.
  - [MobDev.SecurityScan.Layers.SwiftSource](MobDev.SecurityScan.Layers.SwiftSource.md): Static analysis of Swift source under `ios/` using
[swiftlint](https://github.com/realm/SwiftLint).
  - [MobDev.SecurityScan.OsvScanner](MobDev.SecurityScan.OsvScanner.md): Wrapper around the `osv-scanner` CLI (https://google.github.io/osv-scanner/).
  - [MobDev.SecurityScan.OsvScanner.Parser](MobDev.SecurityScan.OsvScanner.Parser.md): Pure parser: `osv-scanner` JSON → `[Finding.t()]`.
  - [MobDev.SecurityScan.Report](MobDev.SecurityScan.Report.md): Aggregate result of a security scan: every layer's `LayerResult`
plus run metadata. The report is the single object handed to
formatters (terminal, JSON, markdown) and the value returned
from `MobDev.SecurityScan.run/1`.
  - [MobDev.SecurityScan.Runner](MobDev.SecurityScan.Runner.md): Orchestrates the scan: invokes each enabled layer in turn,
collects `LayerResult`s, and returns a `Report`.
  - [MobDev.SecurityScan.StateFile](MobDev.SecurityScan.StateFile.md): Read/write the state sidecar for `mix mob.security_scan.log`.
  - [MobDev.Smoke](MobDev.Smoke.md): The decisions behind `mix mob.smoke`, kept free of I/O so each can be
tested against the shapes `agent-device` and `Mob.Diag` really return.
  - [MobDev.StaticNifs](MobDev.StaticNifs.md): Schema, defaults, and C-source generation for the static NIF table.
  - [MobDev.Style](MobDev.Style.md): The styles lane (MOB_STYLES.md), minimum-viable slice: token-only style
packages. A style package ships `priv/mob_style.exs` declaring a theme
module; activation is `config :mob, :styles, [...]` plus
`config :mob, :default_style, :name` in `mob.exs`, and the runtime manifest
carries the resolved set so core can apply the default style's theme at boot.
  - [MobDev.SupportMatrix](MobDev.SupportMatrix.md): Per-feature device requirements + the validation that runs before
`mix mob.deploy` builds anything.
  - [MobDev.TaskHelp](MobDev.TaskHelp.md): Helpers for `--help` / `-h` handling in mob_dev Mix tasks.
  - [MobDev.TaskTargets](MobDev.TaskTargets.md): Shared device-selection policy for tasks that can change device state.
  - [MobDev.TfliteDownloader](MobDev.TfliteDownloader.md): Downloads and caches pre-built TensorFlow Lite native libraries for
Android and iOS so Mob apps can ship the TFLite Nx backend without
building TFLite from source (Bazel).
  - [MobDev.TfliteNif](MobDev.TfliteNif.md): Cross-compiles `tflite_nif.c` (the NIF wrapping TensorFlow Lite's C API)
for one Android or iOS target ABI and archives the result as
`libtflite_nif.a`. The archive gets static-linked into the user app's
main native binary alongside `crypto.a`, `libemlx.a`, and any other
static NIFs.
  - [MobDev.Tunnel](MobDev.Tunnel.md): Manages port tunnels for Android and physical iOS devices.
  - [MobDev.Uninstaller](MobDev.Uninstaller.md): Uninstall a Mob app (or every Mob-prefixed app) from one or more
connected devices.
  - [MobDev.UrlSchemes](MobDev.UrlSchemes.md): Custom URL schemes that open the app (MOB-379): `config :mob_dev,
url_schemes: ["myapp"]` in `mob.exs`. mob delivers the URL to the BEAM as
`{:link, %{url: url, source: :launch | :running}}`; this module only makes the
OS route the URL to the app.
  - [MobDev.ZigBuild](MobDev.ZigBuild.md): Runs a native `zig build` (the iOS simulator/device binary, the Android
per-ABI objects, Zigler NIF cross-compiles) and turns its result into `:ok`
or an error that names what broke.

## Mix Tasks

- Mix Tasks
  - [mix mob.add_nif](Mix.Tasks.Mob.AddNif.md): Scaffolds a new statically-linked NIF in the current Mob project.
  - [mix mob.adopt](Mix.Tasks.Mob.Adopt.md): Adds Mob (mobile framework) to an existing Phoenix-based Elixir project.
  - [mix mob.adopt.bridge](Mix.Tasks.Mob.Adopt.Bridge.md): Patches `assets/js/app.js` and `lib/<web>/components/layouts/root.html.heex`
to wire `window.mob` through a LiveView `phx-hook`. Output matches
`mix mob.new --liveview`.
  - [mix mob.adopt.deps](Mix.Tasks.Mob.Adopt.Deps.md): Adds Mob's two deps to the host project's `mix.exs`
  - [mix mob.adopt.finalize](Mix.Tasks.Mob.Adopt.Finalize.md): Emits a post-install notice with the next steps for the user.
Performs no file changes — purely informational.
  - [mix mob.adopt.mob_app](Mix.Tasks.Mob.Adopt.MobApp.md): Generates the on-device BEAM entry point invoked by Mob's native
shell at app launch
  - [mix mob.adopt.mob_exs](Mix.Tasks.Mob.Adopt.MobExs.md): Writes `mob.exs` — project config you commit (plugin activation, trust,
styles, and portable `mob_dir` / `elixir_lib` defaults) — and ensures
`.gitignore` ignores `mob.local.exs`, the machine-local override file
`mob.exs` imports last.
  - [mix mob.adopt.native](Mix.Tasks.Mob.Adopt.Native.md): Dispatcher — composes `mob.adopt.native.android` and
`mob.adopt.native.ios`.
  - [mix mob.adopt.native.android](Mix.Tasks.Mob.Adopt.Native.Android.md): Walks `priv/templates/mob.new/android/**/*.eex` (resolved from mob_new
— see `MobDev.Adopt.Generator`), renders each with the project's
assigns, and writes them via `Igniter.create_new_file/4` with
`on_exists: :skip`. Then copies the binary static tree
(`priv/static/mob.new/android/**`) via direct `File.copy!/2` since
Igniter's `Rewrite` engine assumes UTF-8 text and would corrupt the
Gradle wrapper jar and PNG icons.
  - [mix mob.adopt.native.ios](Mix.Tasks.Mob.Adopt.Native.Ios.md): Walks `priv/templates/mob.new/ios/**/*.eex` (resolved from mob_new —
see `MobDev.Adopt.Generator`), renders each, and writes via
`Igniter.create_new_file/4` with `on_exists: :skip`. Then copies binary
static iOS assets via direct `File.copy!/2`.
  - [mix mob.adopt.screen](Mix.Tasks.Mob.Adopt.Screen.md): Generates `lib/<app>/mob_screen.ex` — the `Mob.Screen` that opens the
WebView pointed at the host Phoenix endpoint.
  - [mix mob.attest](Mix.Tasks.Mob.Attest.md): Compare a connected device's loaded modules against this build.
  - [mix mob.audit_otp](Mix.Tasks.Mob.AuditOtp.md): Walks an OTP runtime tree and tells you which libraries are dead weight.
  - [mix mob.audit_plugins](Mix.Tasks.Mob.AuditPlugins.md): Scans every activated Mob plugin's Elixir + C source for risky patterns
(see the default ruleset in [`MOB_PLUGIN_SECURITY.md`](https://github.com/GenericJam/mob/blob/master/MOB_PLUGIN_SECURITY.md)).
  - [mix mob.battery_bench_android](Mix.Tasks.Mob.BatteryBenchAndroid.md): Builds a benchmark APK, deploys it, and measures battery drain over time.
  - [mix mob.battery_bench_ios](Mix.Tasks.Mob.BatteryBenchIos.md): Builds a benchmark app, deploys it to a physical iPhone/iPad, and measures
battery drain over time.
  - [mix mob.cache](Mix.Tasks.Mob.Cache.md): Inspects every cache `mix mob.*` writes to outside the project tree, and
(with `--clear`) deletes them. Distinct from `mix clean` (build artifacts
in `_build/`) and `mix deps.clean` (deps in `deps/`) — this targets caches
in your home directory that survive across projects.
  - [mix mob.connect](Mix.Tasks.Mob.Connect.md): Discovers connected Android and iOS devices, sets up USB tunnels,
restarts the app on each device, waits for Erlang nodes to come online,
then drops into an IEx session connected to all of them.
  - [mix mob.deploy](Mix.Tasks.Mob.Deploy.md): Compiles the project then pushes BEAM files to a frozen set of selected
Android and iOS devices.
  - [mix mob.devices](Mix.Tasks.Mob.Devices.md): Scans for connected Android devices (via adb) and iOS simulators/physical
devices (via xcrun simctl / ideviceinfo) and prints their status.
  - [mix mob.doctor](Mix.Tasks.Mob.Doctor.md): Checks your environment, project configuration, OTP caches, and connected
devices, reporting any issues with specific fix instructions.
  - [mix mob.emulators](Mix.Tasks.Mob.Emulators.md): Manage virtual devices: Android emulators (AVDs) and iOS simulators.
  - [mix mob.enable](Mix.Tasks.Mob.Enable.md): Enables one or more optional Mob features by patching `mix.exs`, manifest
files, and generating any required source files.
  - [mix mob.gen.live_screen](Mix.Tasks.Mob.Gen.LiveScreen.md): Generates a paired `Mob.Screen` and Phoenix `LiveView` for LiveView mode apps.
  - [mix mob.icon](Mix.Tasks.Mob.Icon.md): Generates platform icons for the current Mob project.
  - [mix mob.install](Mix.Tasks.Mob.Install.md): Runs first-time setup for a Mob project generated by `mix mob.new`.
  - [mix mob.mutate](Mix.Tasks.Mob.Mutate.md): Mutation-test the lines this branch changed.
  - [mix mob.new_plugin](Mix.Tasks.Mob.NewPlugin.md): Generates the skeleton for a new mob plugin under `plugins/<name>/`.
  - [mix mob.plugin.keygen](Mix.Tasks.Mob.Plugin.Keygen.md): Generates a per-plugin Ed25519 keypair and writes
  - [mix mob.plugin.sign](Mix.Tasks.Mob.Plugin.Sign.md): Signs the plugin in `<dir>` (default: cwd) and writes
`priv/mob_plugin.sig`. The signature covers the SHA-256 hashes of
`priv/mob_plugin.exs` and every file the native build reads from the
plugin (`MobDev.Plugin.Sign.build_inputs/2`, MOB-297) — the manifest
bytes are one of those files, so tampering with the
manifest fails verification. The v2 envelope on disk carries the
signed `file_hashes` list so `MobDev.Plugin.Verify.verify_plugin/1`
can check integrity before it ever `Code.eval_file`s the manifest
(see MOB-74).
  - [mix mob.plugin.trust](Mix.Tasks.Mob.Plugin.Trust.md): Records trust in a signed mob plugin by writing
`config :mob, :trusted_plugins, %{...}` to `mob.exs`.
  - [mix mob.plugin.untrust](Mix.Tasks.Mob.Plugin.Untrust.md): Removes the `config :mob, :trusted_plugins` entry for `plugin_name`
from `mob.exs`. No-op if the plugin wasn't trusted.
  - [mix mob.plugins](Mix.Tasks.Mob.Plugins.md): Lists the Mob plugins this project depends on, with tier, hot-push status,
and whether each is activated.
  - [mix mob.provision](Mix.Tasks.Mob.Provision.md): Registers your app's bundle ID with Apple and downloads an iOS
provisioning profile.
  - [mix mob.publish](Mix.Tasks.Mob.Publish.md): Uploads a release-signed artifact to the platform's app store.
  - [mix mob.push](Mix.Tasks.Mob.Push.md): Compiles the project and hot-pushes updated BEAM modules to all running
Android and iOS devices — no app restart.
  - [mix mob.regen_driver_tab](Mix.Tasks.Mob.RegenDriverTab.md): Regenerates the per-app static-NIF table source files in
`priv/generated/driver_tab_ios.zig` and `priv/generated/driver_tab_android.zig`.
  - [mix mob.regen_plugin_manifest](Mix.Tasks.Mob.RegenPluginManifest.md): Regenerates `priv/generated/mob_plugins.exs` — the host's **runtime plugin
manifest** — from the activated plugins' tier-3/4 manifest sections.
  - [mix mob.release](Mix.Tasks.Mob.Release.md): Builds a release-signed artifact ready to upload to the app store.
  - [mix mob.release.openssl](Mix.Tasks.Mob.Release.Openssl.md): Drives the OpenSSL cross-compile + the OTP crypto NIF static archive
for one target — replaces running `scripts/release/openssl/<plat>.sh`
and `scripts/release/openssl/build_crypto_static_<plat>.sh` in
sequence.
  - [mix mob.release.otp](Mix.Tasks.Mob.Release.Otp.md): Drives `MobDev.Release.OTP.build/2` from the CLI. Replaces the
three `scripts/release/xcompile_*.sh` scripts plus the misplaced
`scripts/release/openssl/_build_otp_android_arm64.sh`.
  - [mix mob.release.publish](Mix.Tasks.Mob.Release.Publish.md): Drives `MobDev.Release.Publish.publish/1` from the CLI. Replaces
`scripts/release/publish.sh`.
  - [mix mob.release.tarball](Mix.Tasks.Mob.Release.Tarball.md): Drives `MobDev.Release.Tarball.build/2` from the CLI. Replaces the
four `scripts/release/tarball_*.sh` scripts.
  - [mix mob.republish](Mix.Tasks.Mob.Republish.md): Convenience wrapper around the per-release flow. Bumps the platform's
build number, rebuilds the release artifact, and uploads to the store.
  - [mix mob.routes](Mix.Tasks.Mob.Routes.md): Walks all `lib/**/*.ex` files and checks that every module passed to
`push_screen/2`, `reset_to/2`, or `pop_to/2` resolves to a loadable module.
  - [mix mob.security_scan](Mix.Tasks.Mob.SecurityScan.md): Audits the project for known vulnerabilities and unsafe code across
every surface a Mob app actually ships
  - [mix mob.security_scan.log](Mix.Tasks.Mob.SecurityScan.Log.md): Scheduled-run helper for the security scan. Designed to be invoked
by cron, GitHub Actions, or any other recurring trigger.
  - [mix mob.selftest](Mix.Tasks.Mob.Selftest.md): Attach to the deployed app on each selected device and run every activated
plugin's `Mob.Plugin.SelfTest` on it, over distribution.
  - [mix mob.server](Mix.Tasks.Mob.Server.md): Starts the Mob dev server and opens it in the browser.
  - [mix mob.setup.google_play](Mix.Tasks.Mob.Setup.GooglePlay.md): Interactive wizard that automates the Google Cloud steps required before
`mix mob.publish --android` can work.
  - [mix mob.smoke](Mix.Tasks.Mob.Smoke.md): Replay the `agent-device` flows in `smoke/` on each selected device, then
check the app's own diagnostics agree that nothing broke.
  - [mix mob.snapshot_loaded](Mix.Tasks.Mob.SnapshotLoaded.md): Asks a connected device's BEAM what modules it has loaded right now.
In interactive mode (Mob's default), a module is loaded only when
something calls into it — so the loaded set after a real user session
is the empirical "actually used" set.
  - [mix mob.styles](Mix.Tasks.Mob.Styles.md): Lists the activated style packages (MOB_STYLES.md, tokens-only tier) with
their themes and which one `config :mob, :default_style` selects.
  - [mix mob.trace_otp](Mix.Tasks.Mob.TraceOtp.md): Runs `MobDev.OtpTrace.Harness` under full call tracing and reports
the runtime modules + MFAs actually exercised.
  - [mix mob.uninstall](Mix.Tasks.Mob.Uninstall.md): Uninstall a Mob app from one or more connected devices.
  - [mix mob.validate_plugin](Mix.Tasks.Mob.ValidatePlugin.md): Validates the `priv/mob_plugin.exs` manifest of the plugin project in the
current directory — a plugin author's pre-publish check.
  - [mix mob.verify_strip](Mix.Tasks.Mob.VerifyStrip.md): Boot-safety verification for stripped Mob app builds.
  - [mix mob.watch](Mix.Tasks.Mob.Watch.md): Watches `lib/` for source changes and automatically compiles + hot-pushes
updated modules to all running Android and iOS devices.
  - [mix mob.watch_stop](Mix.Tasks.Mob.WatchStop.md): Stops a running `mix mob.watch` process.

