Repository navigation
Integrations
Rift exposes a JSON-over-Mach IPC interface for companion applications, status bars, scripts, and other macOS automation. Integrations can either invoke rift-cli or connect directly to Rift's Mach service with a client library.
- Use
rift-clifrom shell scripts, launch agents, SketchyBar plugins, and other command-line workflows. - Use
rift-clientfrom a Rust application or plugin that needs typed requests and event handling. - Use
rift.luafrom Lua. It is a low-level Lua binding for Rift's Mach IPC client. - Use
riftapiwhen you want a higher-level Lua API organized around queries, workspaces, windows, layouts, displays, and events. It builds onrift.luaand is particularly useful in SketchyBar configurations.
All of these clients communicate with the running Rift process; they do not manage windows independently. Rift must be running and its Mach service must be available before requests can succeed.
rift-cli is the simplest integration point and returns JSON, making it suitable for shell scripts and programs that can execute subprocesses.
Query Rift's state:
rift-cli query workspaces
rift-cli query windows
rift-cli query displaysExecute actions:
rift-cli execute window focus left
rift-cli execute workspace switch 2
rift-cli execute workspace set-layout --workspace-id 2 scrollingUse RIFT_CLI_PRETTY=1 for readable JSON. For the complete command reference, including layout persistence and service management, see the rift-cli reference.
Rift can stream events to a Mach subscriber or run a command when an event is emitted. The CLI subscription mode passes event data as the final command argument and provides event-specific environment variables, which makes it convenient for SketchyBar and similar status-bar integrations.
rift-cli subscribe cli \
--event workspace_changed \
--command sh \
--args -c 'sketchybar --trigger rift_workspace_changed RIFT_WORKSPACE_NAME="$RIFT_WORKSPACE_NAME"'The supported event names are workspace_changed, windows_changed, window_title_changed, stacks_changed, and *. See examples of Rift being used from SketchyBar Shell configurations and SketchyBar Lua configurations for community integration ideas.
rift-client is Rift's synchronous Rust client crate. It uses the same Mach service as rift-cli and exposes the shared protocol types for querying state, executing typed commands, and subscribing to typed RiftEvent values.
When developing against this repository, add the client as a path dependency:
[dependencies]
rift-client = { path = "crates/rift-client" }A client can query Rift without shelling out:
use rift_client::RiftMachClient;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = RiftMachClient::connect()?;
let workspaces = client.get_workspaces(None)?;
println!("{workspaces:#?}");
Ok(())
}Subscriptions block until the next matching event arrives:
use rift_client::{EventKind, RiftMachClient};
let client = RiftMachClient::connect()?;
let subscription = client.subscribe(EventKind::WorkspaceChanged)?;
let event = subscription.recv_event()?;The repository includes complete query, listen, and dimmer examples.
rift.lua is a native Lua Mach IPC client. It is useful for embedded Lua environments and status-bar configurations that need direct access to Rift without invoking rift-cli for every request.
The project builds a Lua module at bin/rift.so, which can then be loaded and connected to Rift:
package.cpath = "./bin/?.so;" .. package.cpath
local rift = require("rift")
local client, err = rift.connect()
if not client then error(err) end
local response, err = client:send_request([[{"get_workspaces":{"space_id":null}}]])
if not response then error(err) endRequests use raw JSON strings and responses are decoded into Lua tables. The client also supports callback-based subscriptions for workspace_changed, windows_changed, window_title_changed, stacks_changed, and * (all events). Keep the Lua process alive while subscribed so callbacks can continue to run.
pyrorhythm/riftapi provides a higher-level wrapper around rift.lua. Its modules expose a more convenient Lua interface for common Rift operations, such as querying workspaces and creating or switching them:
local rift = require("riftapi")
local workspaces, err = rift.query.workspaces()
if not workspaces then
error(err)
end
rift.workspace.switch(2)This is a good fit for SketchyBar configurations: use events or periodic refreshes to update the bar, and call rift.workspace.* or other riftapi modules in response to user interaction.
- The clients use Rift's per-user bootstrap service. Set
RIFT_BS_NAMEwhen running multiple Rift instances and connecting to a non-default service. - Queries return current state; subscriptions are intended for reacting to changes.
- Event and command names are part of the Rift protocol and may evolve while Rift is in active development. Check the CLI reference and client examples when upgrading.