Desktop (apps/desktop)
The Clone Desktop tray app. Its job is to capture computer-use events (screen, keyboard, mouse, app focus, browser URL) into MCAP/MKV files on disk and stream them to the Recording layer over a slab-append upload protocol. It is recorder + uploader only — the AI pipelines that previously lived on the desktop (digest summarizer, suggestion popup, on-device LLM) moved off the device.
Stack
- Python 3.11+ (3.13 in the production Nuitka build env)
- Vendored
ocapCLI (GStreamer + hardware H.265) for capture pystray(Windows) /rumps(macOS) traycustomtkinterSettings windowhttpx+keyring(DPAPI / Keychain) for auth + uploadstruststorefor corporate MITM proxy compatibility- Nuitka standalone build → Inno Setup (Windows) / signed + notarized DMG (macOS)
Surface split
| Surface | Concern |
|---|---|
| Desktop | Record + upload. Tray-only — no main window. Tail recording into the Clone server with crash-recovery semantics. |
| Web | Browse, edit, analyze, manage. Memory + Predictions UIs, account settings, billing. |
The desktop client deliberately holds no business state beyond the
upload queue (stream_uploads in SQLite) and OS-keychain refresh
token; everything else is the server's view.
Run it locally
cd apps/desktop
git submodule update --init --recursive
uv venv --python 3.13 && uv pip install -e ".[windows]" # or .[macos]
uv run python -m desktop # tray loads
uv run python -m pytest tests/ # unit + loopback
Build a frozen binary
# Windows
scripts\build_nuitka.bat # → dist\Clone Desktop\CloneDesktop.exe
# → dist\CloneDesktop-Setup-0.1.0.exe
# macOS
bash scripts/build_nuitka.sh # → dist/Clone Desktop.app + DMG
# (signed + notarized when a Developer ID
# is in the keychain)
Frozen-build self-tests
"CloneDesktop.exe" --selftest=keyring_backend # OS keychain round-trip
"CloneDesktop.exe" --selftest=truststore_inject # MITM-proxy CA path
"CloneDesktop.exe" --selftest=upload_loopback # 5 MB byte-equal smoke
"CloneDesktop.exe" --selftest=gst_init # Nuitka×D3D11 bisect tool