Shared protocol types for xclock plugins and extensions.
The kernel sends a JSON Request on stdin and reads a JSON Response from
stdout. Plugins are standalone executables, so the protocol is
language-agnostic and has no Rust ABI requirements.
[dependencies]
xclock-plugin-api = "0.1"use xclock_plugin_api::{read_request, write_response, Response};
fn main() -> std::io::Result<()> {
let request = read_request()?;
let lines = vec![format!("now: {}", request.context.now)];
write_response(&Response::lines(lines))
}Request:
{
"version": 1,
"kind": "widget",
"args": { "cities": ["Madrid", "Tokyo"] },
"context": { "now": "2026-09-10T18:22:01+02:00", "width": 40, "height": 6 }
}Response with static lines:
{ "version": 1, "lines": ["Madrid 18:22", "Tokyo 01:22"] }Response with animation frames:
{
"version": 1,
"lines": [],
"frames": [
{ "delay_ms": 80, "lines": ["frame 1"] },
{ "delay_ms": 80, "lines": ["frame 2"] }
]
}Response with an error:
{ "version": 1, "lines": [], "error": "network unavailable" }Plugins should declare their own runtime budget and return a fallback response when it elapses. The kernel also applies a timeout as a safety net.