selkies/skills/wl-record-pixelflux/SKILL.md
Desktop video recorder via selkies WebSocket capture bridge for selkies-desktop. Use when working with the wl-record-pixelflux candy.
npx skillsauth add overthinkos/overthink-plugins wl-record-pixelfluxInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
| Property | Value |
|----------|-------|
| Install files | charly.yml, task:, pixelflux-record (Python script) |
| Depends | selkies (capture bridge + WebSocket stream), ffmpeg (MP4 muxing) |
Provides pixelflux-record for recording desktop video on selkies-desktop. Connects to the capture bridge at /tmp/charly-capture.sock which relays the same H.264 frames that the browser sees via the selkies WebSocket stream. No direct ScreenCapture API access -- taps into the existing selkies streaming pipeline to avoid creating a second capture instance (the Rust backend only supports one active capture at a time).
Why not wf-recorder? labwc running nested inside pixelflux can't deliver wlr-screencopy frames. The capture bridge bypasses this by tapping into the selkies WebSocket stream directly.
/tmp/charly-capture.sock (started by selkies-capture-server)STREAM\n to request continuous H.264 frame data4-byte length + raw H.264 data pairs-use_wallclock_as_timestamps 1| Property | Value |
|----------|-------|
| Depends | selkies (capture bridge + stream), ffmpeg (muxing) |
| Install | ~/.local/bin/pixelflux-record (Python script) |
| Capture | Via /tmp/charly-capture.sock (selkies WebSocket bridge) |
| Output | MP4 (H.264 video + optional AAC audio) |
| Audio | PulseAudio monitor source via ffmpeg |
# Direct usage
pixelflux-record output.mp4 # 30fps, video only
pixelflux-record output.mp4 --fps 60 # 60fps
pixelflux-record output.mp4 --audio # video + audio
pixelflux-record output.mp4 --fps 60 --audio # 60fps + audio
# Stop with Ctrl-C
record: check verbAuthor record: plan steps (the declarative verb served out-of-process by
candy/plugin-record — no host charly check subcommand for it) and run them with
charly check live selkies-desktop --filter record. A record: start step with
record_mode: desktop + record_audio: true auto-detects pixelflux-record; desktop
interaction is driven with the cdp:/wl: verbs (which keep their host subcommands);
record: stop + artifact: copies the .mp4 out:
pixelflux-rec-start:
check: a desktop recording with audio starts
record: start
context: [deploy]
record_name: demo
record_mode: desktop
record_audio: true
pixelflux-rec-stop:
check: the desktop recording is captured
record: stop
context: [deploy]
record_name: demo
artifact: demo.mp4
artifact_not_uniform: true
selkies process (single ScreenCapture singleton — process-wide)
├── ScreenCapture (captures full composited desktop)
├── WebSocket server :8081 (broadcasts H.264 frames)
└── Capture bridge thread (internal WebSocket client)
└── Unix socket /tmp/charly-capture.sock
└── pixelflux-record connects here (STREAM mode)
└── pipes H.264 frames to ffmpeg
Singleton note: The ScreenCapture instance is process-wide and lives inside the selkies Python process. pixelflux-record never spawns its own capture; it only attaches to the existing STREAM socket. This is architecturally important because pixelflux's WaylandBackend construction is expensive (EGL context + dmabuf allocators + GPU texture pools) and was the subject of a memory leak fix in commits 6be85eb (singleton enforcement) and 7977b91 (per-frame cleanup_texture_cache()). If you ever see two selkies-capture processes inside the container, that's a regression — see /charly-selkies:selkies (Pixelflux Memory Management) for the diagnostic recipe.
selkies-desktop metalayer/charly-selkies:selkies-labwc (via selkies-desktop metalayer)/charly-selkies:selkies-labwc-nvidia (via selkies-desktop metalayer)/charly-check:record -- the record: check verb (record_mode: desktop) auto-detects pixelflux-record/charly-core:charly-update -- Per-instance update pattern used to roll out the per-frame cleanup_texture_cache() fix across live instances/charly-selkies:wl-screenshot-pixelflux -- Screenshot companion (same capture bridge, same singleton)/charly-selkies:wf-recorder -- Alternative for sway-desktop (wlr-screencopy)/charly-selkies:selkies -- Parent candy (provides capture bridge, WebSocket stream, and the ScreenCapture singleton — see Pixelflux Memory Management)/charly-selkies:selkies-desktop-layer -- Metalayer that composes this recorder into the full browser-accessible desktop/charly-selkies:ffmpeg -- Required dependency (MP4 muxing)Use when the user asks about:
wl-record-pixelflux candy/charly-image:layer — candy authoring reference (charly.yml schema, task verbs, service declarations)/charly-check:check — declarative testing (check: block, charly check box, charly check live)tools
Use when authoring or modifying a charly PLUGIN — a candy with a `plugin:` block that contributes Providers (verbs/kinds/deploy-targets/steps/builders/commands), its own CUE schema, builtin (compiled-in) or external (out-of-tree git repo). Covers the unified Provider model, the per-plugin CUE-schema contract (single source → Go params for dev + schema-over-Describe RPC for runtime), the SDK, and the loader.
tools
The CUE data-validation / configuration CLI (cue), pinned to v0.16.1. Use when working with the cue candy, installing the cue binary into a box or onto a target:local dev host, or running the offline schema-vendoring pipeline that feeds charly's egress validation.
tools
CUE EGRESS validation — validating (and, where it adds value, generating) the config files charly WRITES to a system BEFORE the bytes hit disk. MUST be invoked before working on charly/egress.go, the vendored schemas under candy/plugin-egress/egress-schemas/vendor/, the ValidateEgress / registerVendoredEgressKind path, the offline `task cue:vendor` pipeline, or adding an egress schema for any written artifact (cloud-init, k8s manifests, traefik routes, runtime config, install ledger, systemd/quadlet units, ssh_config, libvirt XML).
tools
Kubernetes cluster-probe declarative check verb — the `kube:` check verb (nodes, pods, ingress, storage class, addon health, apply/delete, and arbitrary resource GETs) served out-of-process by the candy/plugin-kube plugin (vendored client-go; no external kubectl required).