# versecafe/mstat

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

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

Visibility: public

Default branch: main

## Resources

- [Source](https://staging.git.cafe/versecafe/mstat/tree/refs%2Fheads%2Fmain?format=markdown)

- [Commit history](https://staging.git.cafe/versecafe/mstat/commits/refs%2Fheads%2Fmain?format=markdown)

- [Issues](https://staging.git.cafe/versecafe/mstat/issues?format=markdown)

- [Pull requests](https://staging.git.cafe/versecafe/mstat/pulls?format=markdown)

- [Stacks](https://staging.git.cafe/versecafe/mstat/stacks?format=markdown)

- [Branches](https://staging.git.cafe/versecafe/mstat/branches?format=markdown)

- [Tags](https://staging.git.cafe/versecafe/mstat/tags?format=markdown)

Snapshot commit: 5aa3dbe04909ee7b23e470f7a4355340e3f8d1ef

## README

[README.md](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](/api/repos/versecafe/mstat/image?path=resources%2Fscreenshot.png&ref=HEAD&oid=5aa3dbe04909ee7b23e470f7a4355340e3f8d1ef)

## 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](/versecafe/mstat/blob/5aa3dbe04909ee7b23e470f7a4355340e3f8d1ef/LICENSE?format=markdown)

