Packages
mob_new
0.3.5
0.4.20
0.4.19
0.4.18
0.4.17
0.4.16
0.4.15
0.4.14
0.4.13
0.4.12
0.4.11
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.16
0.3.15
0.3.14
0.3.13
0.3.12
0.3.11
0.3.10
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.45
0.1.44
0.1.43
0.1.42
0.1.40
0.1.33
0.1.30
0.1.29
0.1.28
0.1.27
0.1.26
0.1.25
0.1.24
0.1.23
0.1.21
0.1.20
0.1.19
0.1.18
0.1.17
0.1.16
0.1.15
0.1.14
0.1.12
0.1.11
0.1.10
0.1.9
0.1.8
0.1.7
0.1.6
0.1.5
0.1.4
0.1.3
0.1.2
0.1.1
0.1.0
Project generator for the Mob mobile framework
Current section
Files
Jump to
Current section
Files
CHANGELOG.md
# Changelog
All notable changes to **mob_new** (the project generator for Mob) are documented here.
Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). Versioning: [SemVer](https://semver.org/spec/v2.0.0.html).
Full module documentation: [hexdocs.pm/mob_new](https://hexdocs.pm/mob_new).
---
## [0.3.5]
### Fixed
- `beam_jni.c.eex`: restored the closing `}` for `nativeDeliverVendorUsbEvent`. Without it, clang sees nested function definitions and rejects every `JNIEXPORT` that follows ("function definition is not allowed here") — C compilation fails immediately on any project generated from 0.3.3/0.3.4.
- `MobBridge.kt.eex`: removed three duplicate imports (`IntentFilter`, `ConcurrentHashMap`, `AtomicInteger`). Each now appears exactly once in the alphabetised bottom-of-file import block. kotlinc was rejecting with "Conflicting import" so `gradleDebug` failed on any project generated from 0.3.3/0.3.4.
- `beam_jni.c.eex`: removed a 276-line duplicate Bluetooth Classic JNI block (lines 533-808 mirrored 256-531 verbatim). Caused "redefinition of `Java_..._MobBridge_nativeDeliverBt*`" errors at compile time. The canonical first block stays. (Surfaced by the new `clang -fsyntax-only` test below — string-match generator-test assertions still passed because the substrings exist, just twice.)
All three regressions were introduced by the 0.3.3 BT-PR merge taking the union of imports / blocks during conflict resolution, when the 0.3.2 fix had specifically de-duplicated them. Reported by external user on master 2026-05-17.
### Added
- `MobNew.Templates.Lint` — module of structural lints for generator-rendered native source files. 8 checks: `balanced_braces`, `balanced_parens`, `balanced_brackets`, `no_eex_leaks`, `unique_kotlin_imports`, `unique_swift_imports`, `external_fun_jni_consistency`, plus `check_kotlin/1` / `check_c/1` / `check_swift/1` aggregate functions. Returns a list of issue maps; empty list = clean. 25 unit tests cover each check red-then-green.
- Generator tests now use `Lint.check_kotlin/1` and `Lint.check_c/1` instead of inline brace-counting + import-dedup logic. Single source of truth; clearer failure messages.
- New cross-file consistency test: asserts every `external fun nativeFoo(...)` in MobBridge.kt has a matching `Java_..._MobBridge_nativeFoo(...)` JNI thunk in beam_jni.c. Catches "added the Kotlin side but forgot the C thunk" (or the reverse).
- New `clang -fsyntax-only` test (`@tag :requires_android_ndk`) that invokes the NDK's clang against the rendered `beam_jni.c`. Catches the full class of "actually broken C" — typos, wrong arg counts, duplicate definitions — that tier-1 structural lints can miss. Skips cleanly when the Android NDK isn't installed (mirrors the existing `:requires_zig` pattern).
## [0.3.4]
### Added
- `CLAUDE.md` "Release flow" section pointing at the canonical process
in [`mob/RELEASE.md`](https://github.com/GenericJam/mob/blob/master/RELEASE.md)
(URL form so it resolves without a local mob checkout). mob_new
specifics: generator tests need `MOB_DIR=/Users/kevin/code/mob` set
when running from a worktree (the resolver looks for `mob` alongside
the project and the worktree path breaks that assumption).
- `.githooks/pre-push` — same script shipped in mob (cheap preflight
always, release preflight when `mix.exs` changed). Activate per
clone or worktree with `git config core.hooksPath .githooks`.
## [0.3.3]
### Added
- Bluetooth Classic peripheral codegen (`MobBridge.kt.eex`, `beam_jni.c.eex`, `AndroidManifest.xml.eex`) — generated apps now include the Kotlin BroadcastReceivers, JNI native_* externs, and Android permissions for the `Mob.Bt` runtime API (HFP / SPP / HID). Companion to `mob` 0.6.5's `Mob.Bt` module. Contributed by [@HeroesLament](https://github.com/HeroesLament) ([#4](https://github.com/GenericJam/mob_new/pull/4)).
## [0.3.2]
### Fixed
- HexDocs `source_url` and `source_url_pattern` pointed at the wrong repo (`mob` instead of `mob_new`) and at a non-existent `/mob_new/` subdirectory prefix; the rendered `</>` glyphs all 404'd. Corrected to `github.com/genericjam/mob_new/blob/master/...`.
- Template fix: `beam_jni.c.eex` was missing the closing `}` for `nativeDeliverVendorUsbEvent` before the BT JNI thunks began — every subsequent `JNIEXPORT void JNICALL` was rejected by clang with "function definition is not allowed here". Generator tests never caught this because they grep rendered output, not compile it.
- Template fix: `MobBridge.kt.eex` duplicated three imports (`IntentFilter`, `ConcurrentHashMap`, `AtomicInteger`) alongside the BT Bluetooth* imports; kotlinc rejected with "Conflicting import".
- Template fix: `MobBridge.kt.eex` missing `androidx.compose.foundation.layout.fillMaxSize` import for the GpuView compile-error overlay.
- Template fix: orphan comment in the import block confused ktlint's `import-ordering` rule (no autocorrect available when imports are interleaved with comments).
### Added
- `.github/workflows/test.yml` — runs `mix test`, `mix format --check-formatted`, `mix credo --strict`, and `mix deps.audit` on push to master and on every PR.
- `.github/workflows/release.yml` — on tag push, creates a GitHub Release whose body is the matching `## [X.Y.Z]` section from this changelog.
## [0.3.1]
### Added
- Bluetooth Classic template scaffolding: `MobBridge.kt.eex` gains the Kotlin BroadcastReceivers, `external fun nativeDeliver*` JNI declarations, and Compose wiring for the `Mob.Bt` runtime API (HFP / SPP / HID). `AndroidManifest.xml.eex` gains the matching modern + legacy Bluetooth permissions. `beam_jni.c.eex` gains the per-event JNI thunks. (Generator tests cover the rendered template's external strings; manual on-device verification per the CLAUDE.md convention.)
- `Mob.GpuView` Android backend (GLES 3.0): `MobBridge.kt.eex` gains `MobGpuView` composable + `MobGpuSurfaceView` + `MobGpuRenderer`, mirroring the iOS `MobGpuView.swift` shipped in mob 0.6.4. Same `%{ios: "...MSL...", android: "...GLSL ES..."}` cross-platform shader contract; std140-ish uniform packing matches the iOS Swift packer (scalar/vec2/vec4 with natural alignment). Translucent red compile-error overlay on shader failure, matching iOS behavior.
- Generator-test coverage for both surfaces — asserts the rendered template contains the expected composables, classes, imports, and dispatch entries.
## [0.3.0] and earlier
Earlier releases predate this changelog; consult the [tag list](https://github.com/genericjam/mob_new/tags) and the per-tag commit messages for history.