# smix-ffi

UniFFI v0.29+ scaffolding crate for smix v7 cross-language SDK initiative.

## Status

v7.0 c2 — MVP scaffolding. Single function `resolve_selector` exposed via UDL.

v7.0 c3+ will expand to ~10 runner async fn covering act / sense per
[design.md §3 D6 + D8](../../docs/plan-cold/v7-sdk-design.md). Per spike #4
(decomposition report `docs/plan-history/v7.0-c1-decomposition-report.md`),
each async endpoint will gain a sibling `cancel_{op}(handle)` for
cancellation (UniFFI does not internally support coroutine cancellation).

## Build pipeline

```bash
# Workspace dev test (macOS host)
cargo build -p smix-ffi
cargo test  -p smix-ffi

# iOS sim slice (v7.0 c3 起)
cargo build -p smix-ffi --target aarch64-apple-ios-sim --release

# Android sim slice (v7.0 c4 起)
cargo ndk -t arm64-v8a -t x86_64 build --release

# Swift bindings generation (v7.0 c3)
uniffi-bindgen-swift target/.../libsmix_ffi.a src/smix.udl --out-dir bindings/swift

# Kotlin bindings generation (v7.0 c4)
uniffi-bindgen generate src/smix.udl --language kotlin --out-dir bindings/kotlin

# XCFramework packaging (v7.0 c3)
xcodebuild -create-xcframework \
  -library target/aarch64-apple-ios-sim/release/libsmix_ffi.a -headers include \
  -output dist/SmixCoreFFI.xcframework
```

## Architecture

Wraps stone API (`smix-selector` + `smix-selector-resolver` + `smix-screen`)
into UDL-defined FFI surface. UniFFI generates:
- Rust scaffolding (C-ABI extern "C" fns + RustCallStatus + RustBuffer marshalling)
- Swift bindings (typed Swift API with `async throws` + `Sendable`)
- Kotlin bindings (typed Kotlin API with `suspend fun` + sealed class errors)

Per [design.md §10 iron rule §9 #13](../../docs/plan-cold/v7-sdk-design.md),
this FFI ships only to SDK consumers (XCUITest target / instrumentation test
target / Expo dev-client), **NEVER linked into app binary**. Release app
build has 0 `smix-ffi` bytes.

## License

Apache-2.0 OR MIT (workspace inherited).
