RheoclesREE-oh-kleez

Draft. Written against the spec, ahead of the code. The words are the intent; the software is not there yet.

Getting started

Install it, let macOS ask its questions, find the token, and record one take two ways — from the popover and from a shell.

Rheocles is a menu bar app that bundles a headless daemon, rheocles-core. The app is a thin client of the daemon over the same API you get. Launch the app and the daemon comes up on localhost:7447; quit the app and it stays until nothing is talking to it.

Install

Homebrew — not live until the first release
brew install --cask artisan-build/tap/rheocles

Or the disk image from the releases page. The app, every nested binary and the disk image are Developer ID signed, notarized and stapled; Gatekeeper opens it without a right-click.

Requirements. Apple Silicon, macOS 15 Sequoia or later. The floor is Sequoia because that is where SCRecordingOutput and process-level Core Audio taps became dependable, and Rheocles uses both.

Permissions

macOS asks for each device class the first time it is needed, and Rheocles does not ask ahead of that — with one exception it cannot avoid.

macOS asks for when where it lives afterwards
a camera Camera the first arm System Settings → Privacy & Security → Camera
a microphone Microphone the first arm … → Microphone
system audio System Audio Recording the first arm … → Screen & System Audio Recording
displays and windows Screen Recording the first GET /streams — opening the popover … → Screen & System Audio Recording

The exception is Screen Recording: without it there are no displays to list, so nothing could ever be armed to trigger the prompt. The first stream list raises it once, and the grant takes effect on the daemon’s next launch — quit the app and open it again, and the displays are there.

The token

Every request needs a bearer token, on every transport. You do not have to go and get it. It is written to

~/Library/Application Support/Rheocles/token

with mode 0600, so any app running as you can read it and is paired with zero clicks. That is how Pteroprompter and the NativePHP app pair. Anything that cannot read a file gets the same token as a pairing code in the popover’s settings, where it can also be rotated — rotation invalidates the old one for everyone.

Terminal window
TOKEN="$(cat ~/Library/Application\ Support/Rheocles/token)"
curl -s -H "Authorization: Bearer $TOKEN" localhost:7447/
GET / — discovery
{ "name": "Rheocles", "version": "0.1.0", "hostname": "studio.local",
"machineId": "…", "outputRoot": "/Users/len/Movies/Rheocles",
"freeBytes": 812345678912, "auth": "bearer",
"ports": { "http": 7447, "ws": 7448 } }

Everything Rheocles ever tells you about a file is a path relative to outputRoot. Store the relative path; join it to the root only if you need an absolute one.

The first take, from the popover

  1. Click the mark in the menu bar. Every stream on the machine is listed — cameras, microphones, displays, system audio. Windows are hidden until Show windows is on in settings.
  2. Toggle arm on the ones you want. The row changes to ochre and the menu bar mark draws in outline: the device is live and costing CPU.
  3. Press Record. Every armed stream starts writing. The mark fills, the elapsed clock runs.
  4. Press Stop. The take folder under the output root has one file per stream and a manifest.json that describes them.

The first take, from a shell

The popover’s Record button is the one-click form, POST /record. The two-step form is what a client uses when it needs to know where the files will be before frame one:

create, cue, stop
H="Authorization: Bearer $(cat ~/Library/Application\ Support/Rheocles/token)"
B=localhost:7447
curl -s -H "$H" $B/streams # ids and armed state
curl -s -H "$H" -X POST $B/streams/camera:0x2300000fd9009c/arm -d '{"armed":true}'
curl -s -H "$H" -X POST $B/takes -d '{"name":"ep12"}' # → id and every path; not recording
curl -s -H "$H" -X POST $B/takes/tk_7f3a/start # the cue
curl -s -H "$H" -X POST $B/takes/tk_7f3a/stop
curl -s -H "$H" $B/takes/tk_7f3a # the manifest