# README.md · versecafe/mstat

[View on GitCafe](https://staging.git.cafe/versecafe/mstat/blob/HEAD/README.md)

Repository: [versecafe/mstat](https://staging.git.cafe/versecafe/mstat)

Visibility: public

Requested revision: HEAD

Commit: 5aa3dbe04909ee7b23e470f7a4355340e3f8d1ef

Blob: 6b9a88d9a2fa6bb13f7dab6a9f92872ba66c5a1e

Size: 2078 bytes

[Immutable source](https://staging.git.cafe/versecafe/mstat/blob/5aa3dbe04909ee7b23e470f7a4355340e3f8d1ef/README.md?format=markdown)

````
# Mstat

A tiny native macOS menu-bar system monitor with a Zig sampling engine and a
Swift/AppKit/SwiftUI interface. It shows CPU usage, reclaimable-memory-adjusted
usage, memory pressure, swap, and CPU temperature.

![Mstat menu bar popover](resources/screenshot.png)

## Requirements

- macOS 13 or newer
- Zig 0.16.0
- Xcode command-line tools with the macOS SDK

## Build and run

```sh
zig build app
open zig-out/Mstat.app
```

Or build and launch it in one step:

```sh
zig build run
```

For a one-shot metrics check without opening AppKit:

```sh
zig build once
zig build once-json
```

`zig build` is the only build entry point. It builds the Zig engine as a static
library, invokes `swiftc`, and assembles `Mstat.app`; no Makefile or Xcode project
is required.

The Zig engine samples on a `std.Io` concurrent task and keeps ten minutes of
timestamped one-second snapshots. Swift polls the latest completed snapshot, so
Mach, sysctl, and AppleSMC calls never run on the main thread. The collapsed
menu-bar item uses an adaptive 20-second refresh gate. While its popover is open,
headline metrics update every second and the downsampled chart refreshes every
five seconds.

The popover uses a restrained SwiftUI layout with a neutral CPU chart, SF
Symbols, numeric transitions, monospaced digits, and system Reduce Motion. Its
menu-bar display mode can be CPU, temperature, memory, a configurable pair of
metrics, or a configurable symbol. The selections persist in `UserDefaults`.
The thermometer is filled directly from 0–100% for a 0–100°C reading.

Temperature uses the undocumented AppleSMC IOKit user client. The current
fallback sensor set is verified on an M3 Pro; unsupported machines display an
em dash instead of inventing a value. No privileged helper is used.

## Engine ABI

The UI talks to an opaque engine through the small C header in
`src/mstat_engine.h`: create/destroy, copy the current snapshot, and copy history.
No Swift or AppKit objects cross into Zig, and there are no callbacks across the
language boundary.

## License

[MIT](LICENSE)

````
