Metadata-Version: 2.5
Name: meta-neural-py
Version: 0.1.0a1
Summary: Experimental direct Meta Neural Band access for Python
License-Expression: MIT
License-File: LICENSE
License-File: NOTICE
Classifier: Development Status :: 3 - Alpha
Classifier: Operating System :: MacOS
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: cryptography>=43
Requires-Dist: pyobjc-framework-corebluetooth>=10.3; sys_platform == 'darwin'
Requires-Dist: pyobjc-framework-security>=10.3; sys_platform == 'darwin'
Requires-Dist: pyobjc-framework-webkit>=10.3; sys_platform == 'darwin'
Provides-Extra: dev
Requires-Dist: build>=1.2; extra == 'dev'
Requires-Dist: mypy>=1.13; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.9; extra == 'dev'
Provides-Extra: numpy
Requires-Dist: numpy>=1.26; extra == 'numpy'
Provides-Extra: release
Requires-Dist: build>=1.2; extra == 'release'
Requires-Dist: twine>=6; extra == 'release'
Description-Content-Type: text/markdown

# meta-neural-py

An experimental Python 3.11+ library for direct Meta Neural Band access. It
implements the enrolled transport/trust path, explicit Meta ownership ceremony,
typed gestures/motion/EMG, acknowledged stream control, and sensor-only recordings.
There is no Kinesis app, Swift executable, dashboard, or runtime Xcode dependency.

**Development alpha with limited hardware smoke testing.** Standalone enrollment
in explicit missing-band-key compatibility mode, saved-identity reconnection,
gestures, gyro, orientation, and EMG have worked on one band using macOS 26.5.2
and Python 3.12.13. The band's proof remained unverified because Meta omitted its
public key. Short tests had no local queue drops and acknowledged stream shutdown.
Sustained throughput, device packet-loss measurement, other firmware/host versions,
and coordinate calibration remain unvalidated. Linux and Windows support offline
protocol and replay only. No package has been published yet.

```sh
python -m pip install .
meta-neural discover
# Explicit ownership change; opens Meta's sign-in window:
meta-neural enroll DEVICE_UUID
meta-neural gestures DEVICE_UUID
# Timed check with hand/battery reads, event counts, and acknowledged shutdown:
meta-neural test DEVICE_UUID --duration 60 --profile gestures
```

```python
import asyncio
from meta_neural_py import Band, Gesture, Streams

async def main():
    devices = await Band.discover(timeout=5)
    if not devices:
        raise RuntimeError("No band found; put it in pairing mode")
    # Explicitly choose the intended device in a real application.
    async with Band(devices[0].id) as band:
        async with band.subscribe(Streams(gestures=True, gyro=True)) as events:
            async for event in events:
                if isinstance(event, Gesture):
                    print(event.finger, event.action)

asyncio.run(main())
```

`Band.enroll(device_id, auth=MetaAuth(...))` is the explicit first-user setup path.
A fresh P-256 identity goes through BLE identity/nonce, HTTP `pair_request`, BLE
start ownership, HTTP `pair`, BLE finish ownership, mutual trust, and device info.
The library reconnects with that identity before committing it to its own Keychain
namespace. The default login provider hosts Meta's real custom-scheme redirect in
a private WKWebView process; login and HTTP clients are injectable. If Meta omits
the band public key, verification-required enrollment fails explicitly.
For standalone setup with the current service response, an explicit compatibility
mode is available: `meta-neural enroll DEVICE_UUID --allow-missing-band-key` or
`Band.enroll(device_id, allow_missing_band_key=True)`. This mirrors Kinesis's
missing-key behavior: the band must accept our fresh signing identity, but its own
proof cannot be independently verified. This choice persists in our Keychain item;
`band.band_verified` remains `False` for such sessions. Available band keys are
always checked, including in compatibility mode. No Kinesis installation, keys,
or records are needed. Pending enrollment state is retained for diagnosis.

Only one subscription is allowed per Band. Both its entry and exit wait for the
band's accepted flags. Default queue overflow fails visibly; `drop_oldest` and
`drop_newest` are opt-in, with separate counters. Queues also enforce byte and EMG
sample budgets. Reconnect is opt-in with `ReconnectPolicy(attempts=2)` and never
enrolls automatically. All sessions generate fresh encryption material.

`await band.read_hand()`, `await band.set_hand("left")`, and
`await band.read_battery()` provide configuration/status access. Hand writes change
field 10 alone and independently read it back. Optional battery failure returns
`None` or GATT-only status without ending sensor streams. `band.device_info`
retains raw checked fields; firmware/model labels remain unset until validated.

Motion values retain wire units. Quaternion component order is `w,x,y,z` per the
reference, with unvalidated coordinate conventions. EMG supports only unsigned
16×8 ADC batches, 2048 Hz / 16 bits / encoding 0. Install `.[numpy]` for
`EMGBatch.as_numpy()`. Device clock domains remain distinct; receive timestamps
use host monotonic time. Unknown gesture enum codes are preserved.

See [setup](docs/setup.md), [data format](docs/data-format.md),
[troubleshooting](docs/troubleshooting.md), and [validation](docs/validation.md).
Run offline tests with `pip install '.[dev]'` then `pytest`.

The MIT reference is [callbacked/kinesis](https://github.com/callbacked/kinesis/tree/5c78485f48c0758e2ce46ee11d3aaa070d827b75).
See LICENSE and NOTICE. No unlicensed PoC source, real captures, identities,
firmware, or model binaries are distributed. Not affiliated with Meta.
