macpm 0.24__tar.gz → 2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. macpm-2.1/CHANGELOG.md +79 -0
  2. macpm-2.1/MANIFEST.in +6 -0
  3. macpm-2.1/PKG-INFO +286 -0
  4. macpm-2.1/README.md +245 -0
  5. macpm-2.1/RELEASE.md +155 -0
  6. macpm-2.1/macpm/__init__.py +3 -0
  7. macpm-2.1/macpm/__main__.py +3 -0
  8. macpm-2.1/macpm/dump.py +21 -0
  9. macpm-2.1/macpm/ioreport.py +252 -0
  10. {macpm-0.24 → macpm-2.1}/macpm/macpm.py +425 -356
  11. macpm-2.1/macpm/processes.py +681 -0
  12. macpm-2.1/macpm/sampler.py +422 -0
  13. macpm-2.1/macpm/sensors.py +128 -0
  14. macpm-2.1/macpm/smc.py +309 -0
  15. macpm-2.1/macpm/soc.py +210 -0
  16. macpm-2.1/macpm.egg-info/PKG-INFO +286 -0
  17. macpm-2.1/macpm.egg-info/SOURCES.txt +36 -0
  18. {macpm-0.24 → macpm-2.1}/macpm.egg-info/entry_points.txt +1 -0
  19. macpm-2.1/macpm.egg-info/requires.txt +3 -0
  20. macpm-2.1/packaging/README.txt +69 -0
  21. macpm-2.1/packaging/build.sh +63 -0
  22. macpm-2.1/packaging/entry_tui.py +4 -0
  23. macpm-2.1/packaging/install.sh +26 -0
  24. macpm-2.1/packaging/macpm.command +4 -0
  25. macpm-2.1/pyproject.toml +3 -0
  26. macpm-2.1/setup.py +51 -0
  27. macpm-2.1/tests/test_calc_freq.py +32 -0
  28. macpm-2.1/tests/test_cli.py +38 -0
  29. macpm-2.1/tests/test_layout.py +81 -0
  30. macpm-2.1/tests/test_processes.py +157 -0
  31. macpm-2.1/tests/test_sampler.py +35 -0
  32. macpm-2.1/tests/test_sensors.py +89 -0
  33. macpm-0.24/PKG-INFO +0 -118
  34. macpm-0.24/README.md +0 -100
  35. macpm-0.24/macpm.egg-info/PKG-INFO +0 -118
  36. macpm-0.24/macpm.egg-info/SOURCES.txt +0 -12
  37. macpm-0.24/macpm.egg-info/requires.txt +0 -3
  38. macpm-0.24/setup.py +0 -39
  39. {macpm-0.24 → macpm-2.1}/LICENSE +0 -0
  40. {macpm-0.24 → macpm-2.1}/macpm.egg-info/dependency_links.txt +0 -0
  41. {macpm-0.24 → macpm-2.1}/macpm.egg-info/not-zip-safe +0 -0
  42. {macpm-0.24 → macpm-2.1}/macpm.egg-info/top_level.txt +0 -0
  43. {macpm-0.24 → macpm-2.1}/setup.cfg +0 -0
  44. {macpm-0.24/macpm → macpm-2.1/tests}/__init__.py +0 -0
macpm-2.1/CHANGELOG.md ADDED
@@ -0,0 +1,79 @@
1
+ # Changelog
2
+
3
+ ## 2.1 — 2026-11-11
4
+
5
+ ### Changed
6
+
7
+ - The power panel is titled `Power` instead of `CPU+GPU+ANE Power`, and every
8
+ panel title is clipped to its box so a long title never wraps the frame.
9
+ - The Temps & Fans panel now uses its spare rows for CPU/GPU peak temperatures
10
+ and fan limits instead of leaving them blank.
11
+ - Per-core gauges are labelled `E1…` / `P1…` instead of `Core-1` / `C-1`, so
12
+ narrow gauges keep the percentage readable.
13
+
14
+ ### Added
15
+
16
+ - **Temps & Fans panel** in the default view — hottest CPU and GPU sensor in
17
+ °C and the current RPM of every fan, read from `AppleSMC` without root.
18
+ - **Process view** on key `3` — a macmon-style two-box layout: a
19
+ CPU/GPU/RAM summary box (with wired/active/inactive/free memory) and a
20
+ process table with PID, NAME, USER, CPU%, MEM and GPU% columns, sorted with
21
+ `s`, scrolled with `↑`/`↓` and paused with `Space`. The table refreshes
22
+ every 2 seconds to keep macpm's own CPU low. There is no power column.
23
+
24
+ ### Removed
25
+
26
+ - The separate `macpm-sensors` command. The SMC reader is now part of the TUI
27
+ (`macpm.sensors.SensorReader`).
28
+
29
+ ### Fixed
30
+
31
+ - Impossible power peaks (such as `peak: 6208.38W`) caused by coalesced or
32
+ reset Energy Model counters are now discarded instead of being recorded.
33
+ - When the unprivileged Energy Model counters never report, the power panel
34
+ shows `n/a` instead of a misleading `0.00W`; the total is withheld only when
35
+ both CPU and GPU are unreadable.
36
+
37
+ ## 2.0 — 2026-11-10
38
+
39
+ ### Changed
40
+
41
+ - **Rootless by default**: macpm no longer runs `sudo`, `powermetrics` or any
42
+ privileged helper. Data is collected from IOReport, IOKit, `psutil`,
43
+ `sysctl`, `ioreg` and `pmset`.
44
+ - Reworked the sampler into `macpm.sampler`, with ctypes bindings in
45
+ `macpm.ioreport` and SoC/DVFS discovery in `macpm.soc`.
46
+ - The terminal layout, panel titles, charts, colours and key bindings remain
47
+ the same as macpm 0.x.
48
+ - Version bumped to 2.0.
49
+
50
+ ### Added
51
+
52
+ - `macpm-sensors` / `macpm.sensors` — read SMC temperatures and fan speeds
53
+ without root (read-only).
54
+ - `macpm-dump` / `macpm.dump` — print the rootless metrics as JSON for
55
+ debugging.
56
+ - Optional per-core view improvements and reset/peak handling retained from
57
+ 0.24.
58
+ - `--version` flag.
59
+ - Compatibility notes for macOS 12–27, M1–M4 and partial M5/Ultra support.
60
+
61
+ ### Fixed
62
+
63
+ - `--show_cores` now accepts a real boolean value and `--show_cores` alone.
64
+ - Zero-division guards for `--avg < --interval` and for chips without E cores.
65
+ - No child `powermetrics` process is left behind when the TUI exits.
66
+ - `ioreg` output is filtered at the source to avoid retaining tens of MB of
67
+ XML in the Python allocator.
68
+ - Only the required `Energy Model` channels are subscribed, reducing memory
69
+ and CPU usage.
70
+
71
+ ### Removed
72
+
73
+ - `sudo echo` pre-authentication and the `sudo nice powermetrics` subprocess.
74
+ - The `macpm2` development package (merged into `macpm`).
75
+
76
+ ## 0.24
77
+
78
+ - Last 0.x release: `sudo` + `powermetrics` based sampler, Python TUI with
79
+ CPU/GPU/ANE power, RAM, disk and network panels.
macpm-2.1/MANIFEST.in ADDED
@@ -0,0 +1,6 @@
1
+ include README.md
2
+ include CHANGELOG.md
3
+ include RELEASE.md
4
+ include LICENSE
5
+ recursive-include packaging *
6
+ recursive-include tests *.py
macpm-2.1/PKG-INFO ADDED
@@ -0,0 +1,286 @@
1
+ Metadata-Version: 2.4
2
+ Name: macpm
3
+ Version: 2.1
4
+ Summary: Rootless performance monitoring CLI tool for Apple Silicon
5
+ Home-page: https://github.com/visualcjy/macpm
6
+ Author: Jinyu Chen
7
+ Author-email: visualcjy@mail.com
8
+ License: MIT
9
+ Project-URL: Source, https://github.com/visualcjy/macpm
10
+ Project-URL: Issues, https://github.com/visualcjy/macpm/issues
11
+ Project-URL: Changelog, https://github.com/visualcjy/macpm/blob/main/CHANGELOG.md
12
+ Keywords: macpm apple-silicon monitor performance ioReport psutil
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Operating System :: MacOS
20
+ Classifier: Environment :: Console
21
+ Classifier: Topic :: System :: Monitoring
22
+ Requires-Python: >=3.9
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: dashing>=0.1
26
+ Requires-Dist: psutil>=5.9
27
+ Requires-Dist: humanize>=4.0
28
+ Dynamic: author
29
+ Dynamic: author-email
30
+ Dynamic: classifier
31
+ Dynamic: description
32
+ Dynamic: description-content-type
33
+ Dynamic: home-page
34
+ Dynamic: keywords
35
+ Dynamic: license
36
+ Dynamic: license-file
37
+ Dynamic: project-url
38
+ Dynamic: requires-dist
39
+ Dynamic: requires-python
40
+ Dynamic: summary
41
+
42
+ # macpm
43
+
44
+ **Rootless performance monitoring CLI for Apple Silicon.**<br>
45
+ macpm 2.1 reads the same hardware counters as `powermetrics`, but through
46
+ IOReport/IOKit/SMC — no `sudo`, no password, no privileged helper.
47
+
48
+ A Python-based `nvtop`-inspired terminal monitor for Apple Silicon Macs,
49
+ forked from [asitop](https://github.com/tlkh/asitop).
50
+
51
+ ## Demo
52
+
53
+ Default view — CPU/GPU/ANE utilisation and power, memory, temperatures/fans,
54
+ disk I/O and network, updating once per second:
55
+
56
+ ![macpm default view](https://raw.githubusercontent.com/visualcjy/macpm/main/images/macpm_v.gif)
57
+
58
+ Same view in another colour theme (press ← / → to cycle through them):
59
+
60
+ ![macpm cyan colour theme](https://raw.githubusercontent.com/visualcjy/macpm/main/images/macpm.gif)
61
+
62
+ Per-core view (`--show_cores`, or press `2` while running):
63
+
64
+ ![macpm per-core view](https://raw.githubusercontent.com/visualcjy/macpm/main/images/v2.png)
65
+
66
+ ## Highlights
67
+
68
+ - **No sudo required.** `macpm` runs as a normal user process.
69
+ - CPU E/P core utilisation and frequency, plus an optional per-core view
70
+ - GPU utilisation and frequency
71
+ - CPU / GPU / ANE power, rolling average, peaks and throttle state
72
+ - RAM and swap usage
73
+ - CPU/GPU temperature and fan RPM panel (SMC, read-only, no root)
74
+ - Disk IOPS/throughput and network throughput
75
+ - Process view with per-process CPU, memory and GPU usage, sortable with `s`
76
+ - Familiar terminal layout, colours, charts and key bindings from macpm 0.x
77
+
78
+ ## Install
79
+
80
+ Requirements: **Apple Silicon Mac**, **macOS 12+**, **Python 3.9+**.
81
+
82
+ ```sh
83
+ python3 -m pip install --upgrade macpm
84
+ ```
85
+
86
+ Then run:
87
+
88
+ ```sh
89
+ macpm
90
+ ```
91
+
92
+ There is **no `sudo macpm`** since 2.0. Running it with `sudo` still works, but it
93
+ is unnecessary and no longer recommended.
94
+
95
+ Prefer a standalone binary with no Python installation? See
96
+ [Standalone binaries](#standalone-binaries).
97
+
98
+ ## Usage
99
+
100
+ ```text
101
+ macpm [--interval INTERVAL] [--color COLOR] [--avg AVG] [--show_cores [BOOL]] [--version]
102
+ ```
103
+
104
+ | Option | Meaning |
105
+ |---|---|
106
+ | `--interval SECONDS` | Sampling and display interval (default `1`) |
107
+ | `--color 1-8` | Display colour (default `2`) |
108
+ | `--avg SECONDS` | Averaging window for power values (default `30`) |
109
+ | `--show_cores [BOOL]` | Start in the per-core view |
110
+ | `--version` | Print the version |
111
+
112
+ Keys:
113
+
114
+ ```text
115
+ q / ESC quit
116
+ ← / → change colour
117
+ 1 / 2 / 3 default / per-core / process view
118
+ s cycle the process sort column (process view)
119
+ ↑ / ↓ scroll the process list (process view)
120
+ Space pause / resume the process list (process view)
121
+ Ctrl+R reset peaks
122
+ ```
123
+
124
+ ## Colour themes
125
+
126
+ Pick one with `--color N`, or press ← / → while macpm is running. The default
127
+ is `2` (green).
128
+
129
+ | | |
130
+ |---|---|
131
+ | **1 — red**<br>![colour 1: red](https://raw.githubusercontent.com/visualcjy/macpm/main/images/4.png) | **2 — green (default)**<br>![colour 2: green](https://raw.githubusercontent.com/visualcjy/macpm/main/images/5.png) |
132
+ | **3 — yellow**<br>![colour 3: yellow](https://raw.githubusercontent.com/visualcjy/macpm/main/images/6.png) | **4 — blue**<br>![colour 4: blue](https://raw.githubusercontent.com/visualcjy/macpm/main/images/7.png) |
133
+ | **5 — magenta**<br>![colour 5: magenta](https://raw.githubusercontent.com/visualcjy/macpm/main/images/8.png) | **6 — cyan**<br>![colour 6: cyan](https://raw.githubusercontent.com/visualcjy/macpm/main/images/1.png) |
134
+ | **7 — white**<br>![colour 7: white](https://raw.githubusercontent.com/visualcjy/macpm/main/images/2.png) | **8 — grey**<br>![colour 8: grey](https://raw.githubusercontent.com/visualcjy/macpm/main/images/3.png) |
135
+
136
+ ## Why no sudo?
137
+
138
+ macpm 0.x called `sudo powermetrics`. In 2.0 the sampler reads the underlying
139
+ counters directly. The data is not secret; the old `powermetrics` CLI simply
140
+ requires root and Apple's private entitlements.
141
+
142
+ | Metric | Source |
143
+ |---|---|
144
+ | CPU E/P load and frequency | IOReport `CPU Stats` performance states |
145
+ | Per-core load | IOReport `CPU Core Performance States` |
146
+ | GPU load and frequency | IOReport `GPU Stats` / `GPU Performance States` |
147
+ | CPU / GPU / ANE power | IOReport `Energy Model` |
148
+ | RAM / swap | `psutil` |
149
+ | Disk / network | `psutil` counters |
150
+ | Per-process CPU / memory | `psutil`, plus `/bin/ps` for other users |
151
+ | Per-process GPU | `IOAccelerator` user clients in the IORegistry |
152
+ | CPU/GPU temperature, fan RPM | `AppleSMC` via the IOKit user client |
153
+ | Thermal throttle | `pmset -g therm` |
154
+ | SoC name / core counts | `sysctl` |
155
+ | GPU core count | `ioreg` `gpu-core-count` |
156
+
157
+ The DVFS frequency tables are parsed from the `pmgr` IORegistry node;
158
+ M1–M3 store Hz there, M4+ store kHz.
159
+
160
+ ## Temperatures and fans
161
+
162
+ The default view has a **Temps & Fans** box next to the memory gauge. It shows
163
+ the hottest CPU and GPU sensor in °C and the current RPM of every fan, for
164
+ example:
165
+
166
+ ```text
167
+ ┌ Temps & Fans ──────────────────────────┐
168
+ │ CPU 52.4°C GPU 43.1°C │
169
+ │ Fan 1 2318 rpm Fan 2 2502 rpm │
170
+ └────────────────────────────────────────┘
171
+ ```
172
+
173
+ The values come from `AppleSMC` through the IOKit user client (read-only, no
174
+ root). SMC key names differ between chip generations, so the CPU/GPU sensor
175
+ groups are selected per chip family and a missing key is simply shown as `--`.
176
+ Fan **control** requires root and is not implemented.
177
+
178
+ ## Process view
179
+
180
+ Press `3` for a macmon-style two-box layout. The top box is titled with the
181
+ SoC and core counts (as in views 1/2) and keeps the top-style CPU (E/P
182
+ percentages and frequencies), GPU (%, MHz), RAM/swap and
183
+ wired/active/inactive/free memory summary. The second box is the
184
+ process table with `PID`, `NAME`, `USER`, `CPU%`, `MEM` and `GPU%`; there is no
185
+ power column. The list is sorted by CPU usage by default; press `s` to cycle
186
+ through CPU → MEM → GPU → PID → NAME → USER, and `↑` / `↓` to scroll. The
187
+ header shows the current sort column and direction. Press `Space` to pause the
188
+ list while you scroll through it; the footer changes to `Space resume` and the
189
+ summary keeps updating. The process table refreshes every 2 seconds (or
190
+ `--interval`, if larger) to keep macpm's own CPU usage low; the summary above
191
+ it refreshes every interval. macpm's own process is listed as `macpm`.
192
+
193
+ Per-process CPU and memory come from `psutil`, with `/bin/ps` for processes
194
+ owned by other users (so system processes such as WindowServer appear too).
195
+ GPU usage is the GPU time of the process' `IOAccelerator` user clients;
196
+ processes without a readable GPU client show `0.0`.
197
+
198
+ ## Compatibility
199
+
200
+ Tested on macOS 27.2 with an M3 Max. Behaviour depends more on the chip
201
+ generation than on the macOS version:
202
+
203
+ | Environment | Status |
204
+ |---|---|
205
+ | macOS 12–15, M1–M4 | Works |
206
+ | macOS 26, M1–M4 | Likely works |
207
+ | macOS 26, M5 / M5 Pro / Max | Partial: new CPU tier/channel names (`MCPU`/`SCPU`) and `acc-clusters` DVFS data are not fully handled |
208
+ | macOS 15/26, M1/M2 Ultra | Needs verification: multi-die complex channels may be `ECPU0/1` |
209
+ | macOS 27 | Works on the tested M3 Max; some 27 builds restrict unprivileged `Energy Model` refreshes |
210
+ | Intel Macs | Not supported; the Apple-Silicon IOReport groups are absent |
211
+
212
+ ## Standalone binaries
213
+
214
+ Standalone unsigned/ad-hoc arm64 binary (`macpm`) can be built with
215
+ `packaging/build.sh` and attached to a GitHub release. It bundles Python and
216
+ all dependencies, so the target Mac needs no Python installation.
217
+
218
+ On first launch from a browser download, macOS Gatekeeper may ask you to
219
+ right-click → Open, or you can remove the quarantine flag:
220
+
221
+ ```sh
222
+ xattr -d com.apple.quarantine ./macpm ./macpm.command
223
+ ```
224
+
225
+ See [packaging/README.txt](https://github.com/visualcjy/macpm/blob/main/packaging/README.txt) for details.
226
+
227
+ ## Development
228
+
229
+ ```sh
230
+ git clone https://github.com/visualcjy/macpm.git
231
+ cd macpm
232
+ python3 -m venv .venv
233
+ . .venv/bin/activate
234
+ python3 -m pip install -e .
235
+ python3 -m unittest discover -s tests -v
236
+ ```
237
+
238
+ Build source and wheel distributions:
239
+
240
+ ```sh
241
+ python3 -m pip install build twine
242
+ python3 -m build
243
+ python3 -m twine check dist/*
244
+ ```
245
+
246
+ Build standalone arm64 binaries (build machine needs Python + PyInstaller +
247
+ runtime dependencies; the output has no Python dependency):
248
+
249
+ ```sh
250
+ PYTHON=python3 packaging/build.sh
251
+ ```
252
+
253
+ Release steps are documented in [RELEASE.md](https://github.com/visualcjy/macpm/blob/main/RELEASE.md).
254
+
255
+ ## Troubleshooting
256
+
257
+ - **`macpm: command not found`** — add your Python user-base `bin` directory to
258
+ `PATH`, or run `python3 -m macpm`.
259
+ - **Power readings freeze or show `n/a` on macOS 27** — some builds restrict
260
+ unprivileged `Energy Model` refreshes. CPU/GPU usage and frequency still
261
+ work; a counter that never reports is shown as `n/a` instead of `0.00W`.
262
+ Run `macpm-dump` to inspect the raw values.
263
+ - **M5/Ultra values look wrong** — CPU tier/channel mapping is not complete;
264
+ see the compatibility table.
265
+ - **The Temps & Fans box says `SMC unavailable`** — the AppleSMC user client
266
+ could not be opened on this macOS build; the rest of macpm still works.
267
+ - **A temperature shows `--`** — not every SMC key exists on every chip; the
268
+ reader only reports the keys that are present.
269
+
270
+ ## Changelog
271
+
272
+ See [CHANGELOG.md](https://github.com/visualcjy/macpm/blob/main/CHANGELOG.md). The 2.0 release removes the dependency on
273
+ `sudo`, `powermetrics` and temporary files.
274
+
275
+ ## Credits
276
+
277
+ - [asitop](https://github.com/tlkh/asitop) — original Python TUI this project
278
+ was forked from
279
+ - [macmon](https://github.com/vladkens/macmon) and
280
+ [Stats](https://github.com/exelban/stats) — IOReport/SMC reference
281
+ implementations
282
+ - The IOReport sample-delta and DVFS-table ideas follow those projects
283
+
284
+ ## License
285
+
286
+ MIT. See [LICENSE](https://github.com/visualcjy/macpm/blob/main/LICENSE).
macpm-2.1/README.md ADDED
@@ -0,0 +1,245 @@
1
+ # macpm
2
+
3
+ **Rootless performance monitoring CLI for Apple Silicon.**<br>
4
+ macpm 2.1 reads the same hardware counters as `powermetrics`, but through
5
+ IOReport/IOKit/SMC — no `sudo`, no password, no privileged helper.
6
+
7
+ A Python-based `nvtop`-inspired terminal monitor for Apple Silicon Macs,
8
+ forked from [asitop](https://github.com/tlkh/asitop).
9
+
10
+ ## Demo
11
+
12
+ Default view — CPU/GPU/ANE utilisation and power, memory, temperatures/fans,
13
+ disk I/O and network, updating once per second:
14
+
15
+ ![macpm default view](https://raw.githubusercontent.com/visualcjy/macpm/main/images/macpm_v.gif)
16
+
17
+ Same view in another colour theme (press ← / → to cycle through them):
18
+
19
+ ![macpm cyan colour theme](https://raw.githubusercontent.com/visualcjy/macpm/main/images/macpm.gif)
20
+
21
+ Per-core view (`--show_cores`, or press `2` while running):
22
+
23
+ ![macpm per-core view](https://raw.githubusercontent.com/visualcjy/macpm/main/images/v2.png)
24
+
25
+ ## Highlights
26
+
27
+ - **No sudo required.** `macpm` runs as a normal user process.
28
+ - CPU E/P core utilisation and frequency, plus an optional per-core view
29
+ - GPU utilisation and frequency
30
+ - CPU / GPU / ANE power, rolling average, peaks and throttle state
31
+ - RAM and swap usage
32
+ - CPU/GPU temperature and fan RPM panel (SMC, read-only, no root)
33
+ - Disk IOPS/throughput and network throughput
34
+ - Process view with per-process CPU, memory and GPU usage, sortable with `s`
35
+ - Familiar terminal layout, colours, charts and key bindings from macpm 0.x
36
+
37
+ ## Install
38
+
39
+ Requirements: **Apple Silicon Mac**, **macOS 12+**, **Python 3.9+**.
40
+
41
+ ```sh
42
+ python3 -m pip install --upgrade macpm
43
+ ```
44
+
45
+ Then run:
46
+
47
+ ```sh
48
+ macpm
49
+ ```
50
+
51
+ There is **no `sudo macpm`** since 2.0. Running it with `sudo` still works, but it
52
+ is unnecessary and no longer recommended.
53
+
54
+ Prefer a standalone binary with no Python installation? See
55
+ [Standalone binaries](#standalone-binaries).
56
+
57
+ ## Usage
58
+
59
+ ```text
60
+ macpm [--interval INTERVAL] [--color COLOR] [--avg AVG] [--show_cores [BOOL]] [--version]
61
+ ```
62
+
63
+ | Option | Meaning |
64
+ |---|---|
65
+ | `--interval SECONDS` | Sampling and display interval (default `1`) |
66
+ | `--color 1-8` | Display colour (default `2`) |
67
+ | `--avg SECONDS` | Averaging window for power values (default `30`) |
68
+ | `--show_cores [BOOL]` | Start in the per-core view |
69
+ | `--version` | Print the version |
70
+
71
+ Keys:
72
+
73
+ ```text
74
+ q / ESC quit
75
+ ← / → change colour
76
+ 1 / 2 / 3 default / per-core / process view
77
+ s cycle the process sort column (process view)
78
+ ↑ / ↓ scroll the process list (process view)
79
+ Space pause / resume the process list (process view)
80
+ Ctrl+R reset peaks
81
+ ```
82
+
83
+ ## Colour themes
84
+
85
+ Pick one with `--color N`, or press ← / → while macpm is running. The default
86
+ is `2` (green).
87
+
88
+ | | |
89
+ |---|---|
90
+ | **1 — red**<br>![colour 1: red](https://raw.githubusercontent.com/visualcjy/macpm/main/images/4.png) | **2 — green (default)**<br>![colour 2: green](https://raw.githubusercontent.com/visualcjy/macpm/main/images/5.png) |
91
+ | **3 — yellow**<br>![colour 3: yellow](https://raw.githubusercontent.com/visualcjy/macpm/main/images/6.png) | **4 — blue**<br>![colour 4: blue](https://raw.githubusercontent.com/visualcjy/macpm/main/images/7.png) |
92
+ | **5 — magenta**<br>![colour 5: magenta](https://raw.githubusercontent.com/visualcjy/macpm/main/images/8.png) | **6 — cyan**<br>![colour 6: cyan](https://raw.githubusercontent.com/visualcjy/macpm/main/images/1.png) |
93
+ | **7 — white**<br>![colour 7: white](https://raw.githubusercontent.com/visualcjy/macpm/main/images/2.png) | **8 — grey**<br>![colour 8: grey](https://raw.githubusercontent.com/visualcjy/macpm/main/images/3.png) |
94
+
95
+ ## Why no sudo?
96
+
97
+ macpm 0.x called `sudo powermetrics`. In 2.0 the sampler reads the underlying
98
+ counters directly. The data is not secret; the old `powermetrics` CLI simply
99
+ requires root and Apple's private entitlements.
100
+
101
+ | Metric | Source |
102
+ |---|---|
103
+ | CPU E/P load and frequency | IOReport `CPU Stats` performance states |
104
+ | Per-core load | IOReport `CPU Core Performance States` |
105
+ | GPU load and frequency | IOReport `GPU Stats` / `GPU Performance States` |
106
+ | CPU / GPU / ANE power | IOReport `Energy Model` |
107
+ | RAM / swap | `psutil` |
108
+ | Disk / network | `psutil` counters |
109
+ | Per-process CPU / memory | `psutil`, plus `/bin/ps` for other users |
110
+ | Per-process GPU | `IOAccelerator` user clients in the IORegistry |
111
+ | CPU/GPU temperature, fan RPM | `AppleSMC` via the IOKit user client |
112
+ | Thermal throttle | `pmset -g therm` |
113
+ | SoC name / core counts | `sysctl` |
114
+ | GPU core count | `ioreg` `gpu-core-count` |
115
+
116
+ The DVFS frequency tables are parsed from the `pmgr` IORegistry node;
117
+ M1–M3 store Hz there, M4+ store kHz.
118
+
119
+ ## Temperatures and fans
120
+
121
+ The default view has a **Temps & Fans** box next to the memory gauge. It shows
122
+ the hottest CPU and GPU sensor in °C and the current RPM of every fan, for
123
+ example:
124
+
125
+ ```text
126
+ ┌ Temps & Fans ──────────────────────────┐
127
+ │ CPU 52.4°C GPU 43.1°C │
128
+ │ Fan 1 2318 rpm Fan 2 2502 rpm │
129
+ └────────────────────────────────────────┘
130
+ ```
131
+
132
+ The values come from `AppleSMC` through the IOKit user client (read-only, no
133
+ root). SMC key names differ between chip generations, so the CPU/GPU sensor
134
+ groups are selected per chip family and a missing key is simply shown as `--`.
135
+ Fan **control** requires root and is not implemented.
136
+
137
+ ## Process view
138
+
139
+ Press `3` for a macmon-style two-box layout. The top box is titled with the
140
+ SoC and core counts (as in views 1/2) and keeps the top-style CPU (E/P
141
+ percentages and frequencies), GPU (%, MHz), RAM/swap and
142
+ wired/active/inactive/free memory summary. The second box is the
143
+ process table with `PID`, `NAME`, `USER`, `CPU%`, `MEM` and `GPU%`; there is no
144
+ power column. The list is sorted by CPU usage by default; press `s` to cycle
145
+ through CPU → MEM → GPU → PID → NAME → USER, and `↑` / `↓` to scroll. The
146
+ header shows the current sort column and direction. Press `Space` to pause the
147
+ list while you scroll through it; the footer changes to `Space resume` and the
148
+ summary keeps updating. The process table refreshes every 2 seconds (or
149
+ `--interval`, if larger) to keep macpm's own CPU usage low; the summary above
150
+ it refreshes every interval. macpm's own process is listed as `macpm`.
151
+
152
+ Per-process CPU and memory come from `psutil`, with `/bin/ps` for processes
153
+ owned by other users (so system processes such as WindowServer appear too).
154
+ GPU usage is the GPU time of the process' `IOAccelerator` user clients;
155
+ processes without a readable GPU client show `0.0`.
156
+
157
+ ## Compatibility
158
+
159
+ Tested on macOS 27.2 with an M3 Max. Behaviour depends more on the chip
160
+ generation than on the macOS version:
161
+
162
+ | Environment | Status |
163
+ |---|---|
164
+ | macOS 12–15, M1–M4 | Works |
165
+ | macOS 26, M1–M4 | Likely works |
166
+ | macOS 26, M5 / M5 Pro / Max | Partial: new CPU tier/channel names (`MCPU`/`SCPU`) and `acc-clusters` DVFS data are not fully handled |
167
+ | macOS 15/26, M1/M2 Ultra | Needs verification: multi-die complex channels may be `ECPU0/1` |
168
+ | macOS 27 | Works on the tested M3 Max; some 27 builds restrict unprivileged `Energy Model` refreshes |
169
+ | Intel Macs | Not supported; the Apple-Silicon IOReport groups are absent |
170
+
171
+ ## Standalone binaries
172
+
173
+ Standalone unsigned/ad-hoc arm64 binary (`macpm`) can be built with
174
+ `packaging/build.sh` and attached to a GitHub release. It bundles Python and
175
+ all dependencies, so the target Mac needs no Python installation.
176
+
177
+ On first launch from a browser download, macOS Gatekeeper may ask you to
178
+ right-click → Open, or you can remove the quarantine flag:
179
+
180
+ ```sh
181
+ xattr -d com.apple.quarantine ./macpm ./macpm.command
182
+ ```
183
+
184
+ See [packaging/README.txt](https://github.com/visualcjy/macpm/blob/main/packaging/README.txt) for details.
185
+
186
+ ## Development
187
+
188
+ ```sh
189
+ git clone https://github.com/visualcjy/macpm.git
190
+ cd macpm
191
+ python3 -m venv .venv
192
+ . .venv/bin/activate
193
+ python3 -m pip install -e .
194
+ python3 -m unittest discover -s tests -v
195
+ ```
196
+
197
+ Build source and wheel distributions:
198
+
199
+ ```sh
200
+ python3 -m pip install build twine
201
+ python3 -m build
202
+ python3 -m twine check dist/*
203
+ ```
204
+
205
+ Build standalone arm64 binaries (build machine needs Python + PyInstaller +
206
+ runtime dependencies; the output has no Python dependency):
207
+
208
+ ```sh
209
+ PYTHON=python3 packaging/build.sh
210
+ ```
211
+
212
+ Release steps are documented in [RELEASE.md](https://github.com/visualcjy/macpm/blob/main/RELEASE.md).
213
+
214
+ ## Troubleshooting
215
+
216
+ - **`macpm: command not found`** — add your Python user-base `bin` directory to
217
+ `PATH`, or run `python3 -m macpm`.
218
+ - **Power readings freeze or show `n/a` on macOS 27** — some builds restrict
219
+ unprivileged `Energy Model` refreshes. CPU/GPU usage and frequency still
220
+ work; a counter that never reports is shown as `n/a` instead of `0.00W`.
221
+ Run `macpm-dump` to inspect the raw values.
222
+ - **M5/Ultra values look wrong** — CPU tier/channel mapping is not complete;
223
+ see the compatibility table.
224
+ - **The Temps & Fans box says `SMC unavailable`** — the AppleSMC user client
225
+ could not be opened on this macOS build; the rest of macpm still works.
226
+ - **A temperature shows `--`** — not every SMC key exists on every chip; the
227
+ reader only reports the keys that are present.
228
+
229
+ ## Changelog
230
+
231
+ See [CHANGELOG.md](https://github.com/visualcjy/macpm/blob/main/CHANGELOG.md). The 2.0 release removes the dependency on
232
+ `sudo`, `powermetrics` and temporary files.
233
+
234
+ ## Credits
235
+
236
+ - [asitop](https://github.com/tlkh/asitop) — original Python TUI this project
237
+ was forked from
238
+ - [macmon](https://github.com/vladkens/macmon) and
239
+ [Stats](https://github.com/exelban/stats) — IOReport/SMC reference
240
+ implementations
241
+ - The IOReport sample-delta and DVFS-table ideas follow those projects
242
+
243
+ ## License
244
+
245
+ MIT. See [LICENSE](https://github.com/visualcjy/macpm/blob/main/LICENSE).