Extend VM Service Linux Support

Nucleic-Session: 44D29355-D1D8-4327-97B6-B1AEBD5EDE57
Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
2026-07-08 05:45:09 -07:00
co-authored by nucleic
parent 70a64440cd
commit 63f4018382
+41
View File
@@ -0,0 +1,41 @@
# nucleic-linux-agent
The in-guest control agent for Nucleic **Linux** VMs — the counterpart to `guest/NucleicVMAgent`
(the macOS-guest agent). Where the macOS agent is a Swift/AppKit app doing Accessibility +
ScreenCaptureKit + CGEvent, a Linux guest needs none of that: computer-use (screen capture +
mouse/keyboard) runs entirely **host-side** through the guest's virtio-gpu framebuffer and USB HID.
So this agent only carries the two ops the host reaches *into* the guest for:
- **`ping`** — capability/readiness handshake (protocol version + a synthetic display).
- **`exec`** — the streaming shell-exec sub-protocol the host's `MacVMExecChannel` speaks.
## Transport / protocol
NDJSON over `AF_VSOCK` port **2035** — one JSON request object per line, one JSON reply per line. This
mirrors `VMAgentCore.AgentWire` / `MacVMAgentWire` (host side) byte-for-byte; see
`docs/MACOS_VM_NATIVE_AGENT.md` §3–§4 and `docs/LINUX_VM.md`. Keep the port/version/frame keys in
lockstep with those.
`exec` takes over its connection for the life of the command (bidirectional base64 frames: `o`/`e`/`x`
guest→host, `i`/`eof`/`sig` host→guest). The host opens a dedicated connection per exec.
## Build
```sh
./build.sh # → build/nucleic-linux-agent (static arm64 preferred)
```
Dependency-free C so it links fully static and runs on any arm64 Linux guest, and builds in the
Nucleic Linux build container with just `cc`. The base build stages this binary into the guest at
`/usr/local/bin/nucleic-linux-agent` and enables `systemd/nucleic-linux-agent.service`.
## Test
```sh
cc -O2 -pthread -o build/loopback_test test/loopback_test.c && ./build/loopback_test
```
`loopback_test.c` drives the connection handler over a socketpair (transport-independent), covering
ping, exec stdout/stderr/exit, the stdin round-trip, and JSON-escaped commands. `wire_test.c` is the
same round-trip over real `AF_VSOCK` loopback (`VMADDR_CID_LOCAL`) — run it *inside a guest* (or a host
with the `vsock_loopback` module) since many container kernels don't enable vsock loopback.