| Crates.io | sys-mumu |
| lib.rs | sys-mumu |
| version | 0.2.0-rc.5 |
| created_at | 2025-08-16 06:45:58.957611+00 |
| updated_at | 2025-10-07 11:29:19.104612+00 |
| description | System calls and tools plugin for the Mumu ecosystem |
| homepage | https://lava.nu11.uk |
| repository | https://gitlab.com/tofo/mumu-sys |
| max_upload_size | |
| id | 1798062 |
| size | 89,117 |
Version: 0.2.0-rc.3 Repository:
https://gitlab.com/tofo/mumu-sys
License: MIT OR Apache-2.0
sys-mumu is a native (no external binaries) system plugin for the Lava/MuMu runtime. It exposes timestamps, hardware inventory, sensors (temperatures, fans, voltages), fan control, CPU inventory & frequencies, thermal zones, and a streaming watch API that plays nicely with your flow-style code. The public API is stable and namespaced under sys:* with sub-namespaces like sys:hw:* and sys:cpu:*.
This document covers everything in the repository: what it exposes to users, how the data is shaped, the internals that make it work, platform notes, and the legacy/demo assets that remain in the tree.
bash, sensors, or any other external program in the plugin’s runtime paths./proc and /sys readers for:
hwmon (temperatures/fans/voltages)cpufreq (per-core frequencies)/proc/cpuinfo (per-logical-CPU inventory)/sys/class/thermal (thermal zones)sys:hw:watch(interval_ms [, filter]) yields an Iterator of sensor rows at a cadence — ergonomic with flow transforms.KeyedArray or arrays (MixedArray) of KeyedArray rows; row shapes are documented below.All functions are registered by exact name. Multi-segment names (e.g. sys:hw:info) are supported by the runtime.
sys:timestamp_ms() -> long
Milliseconds since UNIX epoch.
sys:timestamp_micro() -> long
Microseconds since UNIX epoch.
sys:hw:info() -> keyed
{
vendor: string, // e.g., "AuthenticAMD", "GenuineIntel" (best-effort)
model: string, // model name (best-effort)
family: string, // CPU family (best-effort)
features: [string], // CPU flags when available
backend: "linux-hwmon" | "null"
}
sys:hw:caps() -> keyed
{ temps:bool, fans:bool, voltages:bool, clocks:bool, thermal:bool }
sys:hw:sensors([filter]) -> [keyed]
Returns a snapshot list of sensor rows. Accepts an optional filter string:
"temp" | "fan" | "volt" | "clock" | "thermal""linux-hwmon", "linux-thermal", etc.Row shape:
{
kind: "temp" | "fan" | "volt" | "clock" | "thermal",
id: string, // e.g., "k10temp:temp1", "nct6798:fan3"
label: string, // human-friendly label when available, else fallback
value: float|int, // temps: °C, fans: rpm, voltages: V, clocks: MHz
unit: "C" | "rpm" | "V" | "MHz",
path: string, // sysfs path when applicable
backend: string // e.g., "linux-hwmon", "linux-thermal"
}
sys:hw:fan_list() -> [keyed]
Lists controllable PWM devices:
{ id:"<chip>:pwmN", label:string, min:int(0), max:int(100), path:string, backend:"linux-hwmon" }
sys:hw:fan_set(id, percent) -> bool | keyed(error)
Set PWM duty to percent (0..100). Accepts <chip>:pwmN or an absolute pwmN sysfs path.
On success: true. On failure (e.g., permission denied):
{ type:"runtime", message:string, id:string, percent:int }
Permissions: writes usually require root or suitable udev rules. Reads do not.
sys:hw:watch(interval_ms [, filter]) -> Iteratorsys:hw:sensors() at a cadence. Between batches, the iterator yields "NO_MORE_DATA" so host poll loops remain responsive. Designed to plug into flow transforms and slog in the REPL.sys:cpu:info() -> [keyed]
One row per logical CPU parsed from /proc/cpuinfo. Keys reflect kernel field names; values are auto-typed when possible.
sys:cpu:frequency() -> [keyed]
Per-CPU current frequency (MHz) from cpufreq if present:
{ cpu:int, cur_freq_mhz:float, path:string, backend:"linux-cpufreq" }
sys:thermal:list() -> [keyed]
Thermal zones from /sys/class/thermal:
{ kind:"temp", id:"thermal_zoneN", label:string, value:float(C), unit:"C", path:string, backend:"linux-thermal" }
KeyedArray (implemented with indexmap) is used for all rows and single-object returns (inventory, caps, error objects). Ordering is stable for displays and tests.
Errors are returned as standard keyed objects with at least:
{ type:"runtime", message:string, ... }
This crate pins core-mumu 0.8.1-rc.5, which does not define a dedicated KeyedError value, so we use KeyedArray consistently.
Streaming semantics: iterators return one item per next_value() when available; otherwise they return "NO_MORE_DATA". This integrates with the REPL/host poller without blocking.
The optional filter parameter in sys:hw:sensors and sys:hw:watch:
"temp"), only rows of that kind are returned."linux-hwmon"), only rows from that backend are returned.Backends included today:
hwmon (linux-hwmon) — temperatures, fans, voltages under /sys/class/hwmon/*.linux-thermal) — OS thermal zones under /sys/class/thermal/*.linux-cpufreq) — per-CPU scaling current frequency.null) — present on non-Linux builds; reports empty snapshots.*info, *caps, *sensors, cpu:info, cpu:frequency, thermal:list) typically read world-readable files under /proc and /sys. Missing nodes simply result in missing rows.sys:hw:fan_set) require privileges to write pwm* sysfs nodes. If the write fails (e.g., EPERM), the function returns a keyed error with a helpful message. Typical solutions:
No public API in this plugin invokes external programs or shells.
src/lib.rs — registration conduitCargo_lock (entrypoint for Lava/MuMu loader).pub mod share; — internals, not user-callablepub mod register; — bridges that register the MuMu functionssys:* functions during Cargo_lock.src/register/** — user-callable bridgesEach file registers one or more public functions with the interpreter. Bridges validate arguments, call the appropriate helpers under share/**, and return MuMu Value objects.
Bridges in this crate:
timestamp.rs → sys:timestamp_ms, sys:timestamp_microhw_info.rs → sys:hw:infohw_caps.rs → sys:hw:capshw_sensors.rs → sys:hw:sensors([filter])hw_fan_list.rs → sys:hw:fan_listhw_fan_set.rs → sys:hw:fan_set(id, percent)hw_watch.rs → sys:hw:watch(interval_ms [, filter])cpuinfo.rs → sys:cpu:infocpufreq.rs → sys:cpu:frequencythermal.rs → sys:thermal:listAll bridges use register::bind_dyn_only to (1) register a dynamic function by name and (2) bind a variable of the same name so calls like sys:hw:info() resolve naturally.
src/share/** — reusable internalswatch_iter.rs
A small engine for periodic producers: spawns a thread that calls a closure at a cadence and pushes produced Values into a channel. A PluginIterator pulls from that channel, returning "NO_MORE_DATA" when empty.
hw/backend.rs
Minimal backend trait and a registry that merges multiple backends (ORs capability booleans, concatenates rows) with a Null fallback.
hw/mod.rs
Owns the global backend registry. On Linux, it installs the linux-hwmon backend at startup and re-exports Linux helpers so bridges can reuse them (e.g., linux_cpuinfo, linux_cpufreq, linux_thermal).
linux_hwmon.rs
Reads /sys/class/hwmon/*:
temp*_input) — millidegrees converted to °Cfan*_input) — rpmin*_input) — millivolts converted to VpwmN, pwmN_enable) and exposes fan list/control.linux_cpuinfo.rs
Parses /proc/cpuinfo into one KeyedArray per logical CPU (auto-typing values). Also provides summarize_cpuinfo() used by hw:info.
linux_cpufreq.rs
Reads cpufreq/scaling_cur_freq per CPU and returns MHz rows.
linux_thermal.rs
Reads /sys/class/thermal/thermal_zone* to provide OS thermal sensors.
sys:hw:watch uses share/watch_iter.rs to:
interval_msValue::KeyedArrayPluginIterator that yields one item per call and returns "NO_MORE_DATA" when the queue is emptyThis design makes it safe in the REPL and in interpreted runs and integrates with the host’s poll loop (and your flow transforms).
examples/sys-command.mu
A legacy/demo example showing a shell-based sys:command pattern. The current plugin does not register sys:command (to keep runtime strictly native). This file is kept for historical reference.
tests/sys_command_test.mu
A legacy test that exercises sys:command. Not run by default with this native build; keep it or adapt it behind a feature if you want to exercise shell execution locally.
All other code paths (timestamps, sensors, frequency, thermal, watch) are fully native and ready to use.
MuMu core: this crate targets core-mumu = "0.8.1-rc.5". That version:
KeyedArray but not a special KeyedError; errors here are returned as keyed objects with type:"runtime".OS support:
[]) when the platform backends are not available.Bug reports and merge requests are welcome at the GitLab repository. To help us reproduce issues quickly, please include:
uname -a)/proc and /sys nodes (paths are reported in every row)sys:* function and arguments used, including any filtersys:hw:sensors) or streaming (sys:hw:watch)We welcome backends for additional platforms (macOS SMC/IOKit, Windows WMI/PDH). The backend trait is intentionally small; feel free to propose extensions.
@tofo) — author & maintainer of the MuMu/Lava ecosystem and this plugin.Licensed under MIT OR Apache-2.0 (dual). See LICENSE for the full text of each license.