- Python 94.1%
- Shell 5.9%
| .forgejo/workflows | ||
| cli | ||
| docs | ||
| node | ||
| scripts | ||
| .gitignore | ||
| LICENSE | ||
| README.md | ||
ua-deck
uConsole cyberdeck for the Unified Assistant mesh.
A self-contained cyberdeck stack for the ClockworkPi uConsole
(Raspberry Pi CM4) — a local ua-node mesh peer running in Docker, plus a
cyberpunk-themed Textual TUI that talks to it
on localhost:8200.
+----------------------------------------------------------------+
| uConsole (CM4 Lite, 4 GB, arm64, microSD) |
| |
| Docker |
| +---- ua-node container ---------------------------+ |
| | MeshModule -> https://agents.lab.lostsource.net | |
| | MemModule, ChatModule (local cache + sync) | |
| | GatewayModule -> 127.0.0.1:8200 | |
| +--------------------------------------------------+ |
| ^ |
| | localhost HTTP / SSE |
| | |
| ua-deck (Textual TUI) --+ |
| streaming chat, mem browser, tasks, frigate |
+----------------------------------------------------------------+
Why two layers?
- The TUI stays trivial. It's a localhost HTTP/SSE client. No Tailscale
handling, no WSS reconnect logic, no token shipping. Just plain HTTP to
127.0.0.1:8200— identical to how the UA web UI talks to its own gateway. - Offline-resilient. Memory and chat history live locally and sync upstream in the background. Search, browse, and compose still work when WiFi flakes.
- First-class mesh identity. The node carries an Apricorn-issued Ed25519
leaf cert and announces itself via
POST /mesh/hello— same trust model as pete-device.
Layout
ua-deck/
├── node/ # ua-node container deployment
│ ├── docker-compose.yml
│ ├── config.yaml # mesh upstream + module wiring
│ ├── env.example # UA_NODE_CERT_FILE, UA_MASTER_PUBKEY_B64, etc.
│ └── systemd/ # ua-deck-node.service (manages docker compose)
│
├── cli/ # Textual TUI client
│ ├── pyproject.toml
│ ├── ua_deck/
│ │ ├── __main__.py
│ │ ├── app.py
│ │ ├── config.py
│ │ ├── api/ # gateway HTTP/SSE client
│ │ ├── auth/ # localhost token reader
│ │ ├── screens/ # main, memory, tasks, frigate, settings
│ │ ├── widgets/ # chat_log, input_bar, tool_drawer, status_bar
│ │ └── themes/
│ │ └── cyberpunk.tcss
│ └── tests/
│
└── docs/
├── PROVISIONING.md # ClockworkOS first-boot
├── CERT_CEREMONY.md # Apricorn mint flow for this node
└── ARCHITECTURE.md
Quick start (development, before uConsole arrives)
The CLI can be developed against a ua-node running on any amd64 host:
# Pull the ua-node image and start it (amd64 host)
cd node
docker compose up -d
# In another terminal, install + run the TUI
cd cli
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
ua-deck
The TUI connects to http://127.0.0.1:8200 by default. Override with
UA_DECK_BACKEND=http://other-host:8200.
Hardware target
| Spec | Value |
|---|---|
| SBC | Raspberry Pi CM4 Lite (socketed, SD-boot) |
| RAM | 4 GB LPDDR4 |
| Arch | linux/arm64/v8 (Cortex-A72) |
| Storage | microSD only (no eMMC — that's what "Lite" means) |
| Display | 5" IPS 1280×720, landscape orientation |
| Char grid | ~150×45 (11-12px font) / ~110×38 (14px) / ~90×30 (16px) |
| Input | Backlit QWERTY + optical trackball |
| OS | ClockworkOS (Debian) |
| Network | Wi-Fi 5 + BT 5.0 + SIM7600G-H LTE Cat-4 + dual GNSS |
| Radio board v2 | RTL2832U+R860 SDR (100 kHz–1.74 GHz, TCXO, bias tee), SX1262 LoRa (860–960 MHz, 22 dBm), GPS+BDS+GNSS, PCF85063A RTC, RJ45 1 Gbps, Type-C side port |
Why Kit RPI-CM4 Lite (vs. Kit A-06 Rockchip RK3399)
Same chassis, same display, same keyboard, same expansion slots — only the compute module differs. We picked CM4 Lite because:
- Software ecosystem. Raspberry Pi OS / Debian aarch64 means Docker, systemd, RAUC, NetworkManager, ModemManager are first-class. RK3399 community stacks lag on kernel/driver updates.
- arm64 pipeline already wired.
linux/arm64is in the unified-assistant buildx matrix (commite806739). RK3399 would mean rebuilding the RAUC integration from scratch. - SD-boot matches pre-provisioning. "Lite" = no eMMC, so
scripts/prepare-sd.shflashes an SD and the user inserts and boots — norpibootUSB-OTG flash path needed. - Socketed module = upgrade path. The CM4 is not soldered. Pull it, drop in a CM5, keep the chassis.
Upgrade path: CM5 Lite drop-in (future)
The uConsole carrier uses the standard 100-pin Hirose connector shared by CM4 and CM5. ClockworkPi confirmed CM5 compatibility on the uConsole carrier; the community has been running CM5s in this chassis. When a swap makes sense:
| Spec | CM4 Lite (today) | CM5 Lite (future) |
|---|---|---|
| SoC | BCM2711 | BCM2712 |
| CPU | 4× Cortex-A72 @ 1.5 GHz | 4× Cortex-A76 @ 2.4 GHz |
| Perf delta | baseline | ~2–3× single-thread, ~2× multi-thread |
| RAM | 1/2/4/8 GB LPDDR4 | 2/4/8/16 GB LPDDR4X |
| GPU | VideoCore VI | VideoCore VII (~2× faster) |
| Peak power | ~6 W | ~9 W (hotter, shorter battery) |
| Cost (4 GB) | ~$45 | ~$70–90 (8 GB ~$120, 16 GB ~$165) |
What CM5 unlocks for ua-deck:
- Local LLM inference becomes viable on a 16 GB CM5 — small quantized models (Qwen2.5-3B 8-bit, small Gemma) run offline. CM4 4 GB can't load them. Aligns with the blackwall directive — substrate independence if the link dies.
- Multi-app mode (Phase 1.5+2) gets cheap — i3 + Firefox + ua-deck + terminal panes on 8+ GB without warming the chassis.
The two preemptive design hooks needed to make a CM5 swap a no-op reflash —
shipping both DTBs in the RAUC bundle and adding a SoC-detection branch to
the healthcheck thermal budget — are tracked in
docs/ROADMAP.md under Phase 1 backlog.
Roadmap
See docs/ROADMAP.md for the full phase plan. Headline:
- Phase 0 (scaffold + provisioning) — ✅ Shipped
- Phase 0.5 (auto-update + auto-rollback) — 🔄 In progress (design + RAUC + arm64 + deck profile shipped; healthcheck next)
- Phase 1 (streaming chat TUI) — 📋 Awaits hardware
- Phase 1.5 (sidebar + embedded terminal pane) — 📋 New, ~3 hrs
- Phase 2 (desktop launcher + audio + Bluetooth) — 📋 New, ~3 hrs
Known blockers (carried over from the bigger UA roadmap)
-
✅ Resolved 2026-06-07: unified-assistantua-nodedoes not yet publishlinux/arm64.e806739addslinux/arm64to the buildx matrix for bothua-nodeandua-mem. Images now publish for amd64 + arm/v7 + arm64. -
✅ Resolved 2026-06-07: unified-assistantnodeprofile is mesh-only.e806739adds adeckprofile inua_node/core/profiles.pywith the full chat surface, mem, mesh, and supporting modules. SetUA_MODULES_PROFILE=deckin the compose file once a deploy with that commit lands. -
First-boot cert ceremony. Requires the Apricorn-mounted master key on an operator workstation. See
docs/CERT_CEREMONY.md.
License
Same as the rest of the UA stack. Air-gap, sovereignty, defense in depth.