Skip to content

plugin-jetkvm

Version 2026.258.1200
Repo box/github.com/opencharly/plugin-jetkvm:v2026.267.2212
Plugin yes — see the plugin reference

OUT-OF-TREE charly plugin serving the jetkvm IP-KVM verb AND the kind: jetkvm device entity — a standalone Go module (go.mod + cmd/serve) that drives a JetKVM device (https://jetkvm.com) without a browser, over JetKVM’s own WebRTC control plane: local login (POST /auth/login-local) -> signaling websocket (/webrtc/signaling/client) -> the “rpc” JSON-RPC 2.0 data channel, the binary “hidrpc” input channel, and the H.264 video track decoded to a PNG by ffmpeg. It is served OUT-OF-PROCESS over go-plugin gRPC via the charly plugin SDK (github.com/opencharly/sdk); charly’s loader fetches this candy’s repo, go-builds the provider binary on the HOST, and connects it via LocalTransport, so the device wire lives HERE, out of charly’s core check surface.

READ-ONLY BY DEFAULT. The device is a physical appliance and is NOT disposable, so every mutating method (keyboard/pointer input, power and ATX/DC control, virtual media, USB gadget, config writes, reboot, firmware update, factory reset) requires the explicit allow_control: true input; without it a mutating method reports a skip naming the gate rather than acting. factory-reset additionally requires it and is never exerciseable from a bed.

The verb’s entire authoring surface lives in this plugin’s own #JetkvmInput (schema/jetkvm.cue), which the host splices onto the base and validates every authored jetkvm: step against; the plugin self-evaluates the shared stdout/stderr/exit_status matchers and the artifact validators (sdk.VerbVerdict / sdk.RunArtifactValidators), so it owns the verdict exactly like every other out-of-process verb.

CONSOLE INSTALLER. Beyond raw input, the plugin serves two higher-level capabilities: the read-only ocr method (capture + tesseract on the host + assert text — the wait-for-screen primitive), and the mutating install method, a configurable console-installer DRIVER that connects ONCE and walks an ordered steps: recipe, OCR-waiting for each screen-unique anchor before sending its key/type/combo input. The recipe is generic DATA supplied by a kind: jetkvm device entity, so one plugin drives any text-console installer with no per-distro code. The OCR wait is the reason it opens one session: a per-step connection would pay a fresh WebRTC handshake for every screen.

Client reuse, not reinvention: the WebRTC/HID wire is vendored from LeeroyDing/jetkvm-mcp (MIT) and conallob/mcp-jetkvm (BSD-3) under internal/kvmclient (see third_party/NOTICE) and rides the SAME github.com/pion/webrtc/v4 stack the JetKVM firmware itself uses. The session/artifact/credential plumbing is charly’s own (sdk.VerbVerdict, sdk.LandArtifact, sdk.RequireModifiers), never a second implementation.

This candy’s plan: — the runnable spec charly check executes against a live deployment. check: steps are idempotent probes; run: steps change state.

Intent Step
check the plugin ships its self-contained CUE schema and provider entrypoint (the files the host reads over Describe and host-builds) — a deterministic probe that fails if either is missing
check the verb and kind capabilities are declared together, so a jetkvm step dispatches AND a kind jetkvm entity is recognized at parse (a probe that fails if either declaration is dropped)
check the jetkvm verb dispatches through the provider registry and reports its documented no-device skip — proving the out-of-process plugin was host-built, connected, and ran its verdict path (a step that FAILS if the verb is unregistered or the module will not build/serve)