macpm 0.23__tar.gz → 2.0__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 (43) hide show
  1. macpm-2.0/CHANGELOG.md +45 -0
  2. macpm-2.0/MANIFEST.in +6 -0
  3. macpm-2.0/PKG-INFO +253 -0
  4. macpm-2.0/README.md +212 -0
  5. macpm-2.0/RELEASE.md +102 -0
  6. macpm-2.0/macpm/__init__.py +3 -0
  7. macpm-2.0/macpm/__main__.py +3 -0
  8. macpm-2.0/macpm/dump.py +21 -0
  9. macpm-2.0/macpm/ioreport.py +252 -0
  10. {macpm-0.23 → macpm-2.0}/macpm/macpm.py +96 -275
  11. macpm-2.0/macpm/sampler.py +365 -0
  12. macpm-2.0/macpm/sensors.py +56 -0
  13. macpm-2.0/macpm/smc.py +289 -0
  14. macpm-2.0/macpm/soc.py +210 -0
  15. macpm-2.0/macpm.egg-info/PKG-INFO +253 -0
  16. macpm-2.0/macpm.egg-info/SOURCES.txt +34 -0
  17. macpm-2.0/macpm.egg-info/entry_points.txt +4 -0
  18. macpm-2.0/macpm.egg-info/requires.txt +3 -0
  19. macpm-2.0/packaging/README.txt +66 -0
  20. macpm-2.0/packaging/__pycache__/entry_sensors.cpython-312.pyc +0 -0
  21. macpm-2.0/packaging/__pycache__/entry_tui.cpython-312.pyc +0 -0
  22. macpm-2.0/packaging/build.sh +73 -0
  23. macpm-2.0/packaging/entry_sensors.py +4 -0
  24. macpm-2.0/packaging/entry_tui.py +4 -0
  25. macpm-2.0/packaging/install.sh +28 -0
  26. macpm-2.0/packaging/macpm.command +4 -0
  27. macpm-2.0/pyproject.toml +3 -0
  28. macpm-2.0/setup.py +52 -0
  29. macpm-2.0/tests/test_calc_freq.py +32 -0
  30. macpm-2.0/tests/test_cli.py +38 -0
  31. macpm-0.23/PKG-INFO +0 -117
  32. macpm-0.23/README.md +0 -99
  33. macpm-0.23/macpm.egg-info/PKG-INFO +0 -117
  34. macpm-0.23/macpm.egg-info/SOURCES.txt +0 -12
  35. macpm-0.23/macpm.egg-info/entry_points.txt +0 -2
  36. macpm-0.23/macpm.egg-info/requires.txt +0 -3
  37. macpm-0.23/setup.py +0 -33
  38. {macpm-0.23 → macpm-2.0}/LICENSE +0 -0
  39. {macpm-0.23 → macpm-2.0}/macpm.egg-info/dependency_links.txt +0 -0
  40. {macpm-0.23 → macpm-2.0}/macpm.egg-info/not-zip-safe +0 -0
  41. {macpm-0.23 → macpm-2.0}/macpm.egg-info/top_level.txt +0 -0
  42. {macpm-0.23 → macpm-2.0}/setup.cfg +0 -0
  43. {macpm-0.23/macpm → macpm-2.0/tests}/__init__.py +0 -0
macpm-2.0/CHANGELOG.md ADDED
@@ -0,0 +1,45 @@
1
+ # Changelog
2
+
3
+ ## 2.0 — 2026-11-10
4
+
5
+ ### Changed
6
+
7
+ - **Rootless by default**: macpm no longer runs `sudo`, `powermetrics` or any
8
+ privileged helper. Data is collected from IOReport, IOKit, `psutil`,
9
+ `sysctl`, `ioreg` and `pmset`.
10
+ - Reworked the sampler into `macpm.sampler`, with ctypes bindings in
11
+ `macpm.ioreport` and SoC/DVFS discovery in `macpm.soc`.
12
+ - The terminal layout, panel titles, charts, colours and key bindings remain
13
+ the same as macpm 0.x.
14
+ - Version bumped to 2.0.
15
+
16
+ ### Added
17
+
18
+ - `macpm-sensors` / `macpm.sensors` — read SMC temperatures and fan speeds
19
+ without root (read-only).
20
+ - `macpm-dump` / `macpm.dump` — print the rootless metrics as JSON for
21
+ debugging.
22
+ - Optional per-core view improvements and reset/peak handling retained from
23
+ 0.24.
24
+ - `--version` flag.
25
+ - Compatibility notes for macOS 12–27, M1–M4 and partial M5/Ultra support.
26
+
27
+ ### Fixed
28
+
29
+ - `--show_cores` now accepts a real boolean value and `--show_cores` alone.
30
+ - Zero-division guards for `--avg < --interval` and for chips without E cores.
31
+ - No child `powermetrics` process is left behind when the TUI exits.
32
+ - `ioreg` output is filtered at the source to avoid retaining tens of MB of
33
+ XML in the Python allocator.
34
+ - Only the required `Energy Model` channels are subscribed, reducing memory
35
+ and CPU usage.
36
+
37
+ ### Removed
38
+
39
+ - `sudo echo` pre-authentication and the `sudo nice powermetrics` subprocess.
40
+ - The `macpm2` development package (merged into `macpm`).
41
+
42
+ ## 0.24
43
+
44
+ - Last 0.x release: `sudo` + `powermetrics` based sampler, Python TUI with
45
+ CPU/GPU/ANE power, RAM, disk and network panels.
macpm-2.0/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.0/PKG-INFO ADDED
@@ -0,0 +1,253 @@
1
+ Metadata-Version: 2.4
2
+ Name: macpm
3
+ Version: 2.0
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.0 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, disk I/O and
54
+ 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
+ - Disk IOPS/throughput and network throughput
74
+ - Optional temperature/fan reader (`macpm-sensors`)
75
+ - Same terminal layout, colours, charts and key bindings as macpm 0.x
76
+
77
+ ## Install
78
+
79
+ Requirements: **Apple Silicon Mac**, **macOS 12+**, **Python 3.9+**.
80
+
81
+ ```sh
82
+ python3 -m pip install --upgrade macpm
83
+ ```
84
+
85
+ Then run:
86
+
87
+ ```sh
88
+ macpm
89
+ ```
90
+
91
+ There is **no `sudo macpm`** in 2.0. Running it with `sudo` still works, but it
92
+ is unnecessary and no longer recommended.
93
+
94
+ Prefer a standalone binary with no Python installation? See
95
+ [Standalone binaries](#standalone-binaries).
96
+
97
+ ## Usage
98
+
99
+ ```text
100
+ macpm [--interval INTERVAL] [--color COLOR] [--avg AVG] [--show_cores [BOOL]] [--version]
101
+ ```
102
+
103
+ | Option | Meaning |
104
+ |---|---|
105
+ | `--interval SECONDS` | Sampling and display interval (default `1`) |
106
+ | `--color 1-8` | Display colour (default `2`) |
107
+ | `--avg SECONDS` | Averaging window for power values (default `30`) |
108
+ | `--show_cores [BOOL]` | Start in the per-core view |
109
+ | `--version` | Print the version |
110
+
111
+ Keys:
112
+
113
+ ```text
114
+ q / ESC quit
115
+ ← / → change colour
116
+ 1 / 2 default view / per-core view
117
+ Ctrl+R reset peaks
118
+ ```
119
+
120
+ ## Colour themes
121
+
122
+ Pick one with `--color N`, or press ← / → while macpm is running. The default
123
+ is `2` (green).
124
+
125
+ | | |
126
+ |---|---|
127
+ | **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) |
128
+ | **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) |
129
+ | **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) |
130
+ | **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) |
131
+
132
+ ## Why no sudo?
133
+
134
+ macpm 0.x called `sudo powermetrics`. In 2.0 the sampler reads the underlying
135
+ counters directly. The data is not secret; the old `powermetrics` CLI simply
136
+ requires root and Apple's private entitlements.
137
+
138
+ | Metric | Source |
139
+ |---|---|
140
+ | CPU E/P load and frequency | IOReport `CPU Stats` performance states |
141
+ | Per-core load | IOReport `CPU Core Performance States` |
142
+ | GPU load and frequency | IOReport `GPU Stats` / `GPU Performance States` |
143
+ | CPU / GPU / ANE power | IOReport `Energy Model` |
144
+ | RAM / swap | `psutil` |
145
+ | Disk / network | `psutil` counters |
146
+ | Thermal throttle | `pmset -g therm` |
147
+ | SoC name / core counts | `sysctl` |
148
+ | GPU core count | `ioreg` `gpu-core-count` |
149
+
150
+ The DVFS frequency tables are parsed from the `pmgr` IORegistry node;
151
+ M1–M3 store Hz there, M4+ store kHz.
152
+
153
+ ## Temperatures and fans
154
+
155
+ The default TUI intentionally stays identical to macpm 0.x, which has no
156
+ temperature/fan panel. The standalone SMC reader is available as:
157
+
158
+ ```sh
159
+ macpm-sensors
160
+ macpm-sensors --json
161
+ ```
162
+
163
+ It reads `AppleSMC` through the IOKit user client (read-only, no root) and
164
+ reports the raw sensor keys present on the chip, fan RPM/min/max, and
165
+ `PSTR`/`PPBR` power rails. Fan **control** requires root and is not
166
+ implemented.
167
+
168
+ ## Compatibility
169
+
170
+ Tested on macOS 27.2 with an M3 Max. Behaviour depends more on the chip
171
+ generation than on the macOS version:
172
+
173
+ | Environment | Status |
174
+ |---|---|
175
+ | macOS 12–15, M1–M4 | Works |
176
+ | macOS 26, M1–M4 | Likely works |
177
+ | macOS 26, M5 / M5 Pro / Max | Partial: new CPU tier/channel names (`MCPU`/`SCPU`) and `acc-clusters` DVFS data are not fully handled |
178
+ | macOS 15/26, M1/M2 Ultra | Needs verification: multi-die complex channels may be `ECPU0/1` |
179
+ | macOS 27 | Works on the tested M3 Max; some 27 builds restrict unprivileged `Energy Model` refreshes |
180
+ | Intel Macs | Not supported; the Apple-Silicon IOReport groups are absent |
181
+
182
+ ## Standalone binaries
183
+
184
+ Standalone unsigned/ad-hoc arm64 binaries (`macpm`, `macpm-sensors`) can be
185
+ built with `packaging/build.sh` and attached to a GitHub release. They bundle
186
+ Python and all dependencies, so the target Mac needs no Python installation.
187
+
188
+ On first launch from a browser download, macOS Gatekeeper may ask you to
189
+ right-click → Open, or you can remove the quarantine flag:
190
+
191
+ ```sh
192
+ xattr -d com.apple.quarantine ./macpm ./macpm-sensors ./macpm.command
193
+ ```
194
+
195
+ See [packaging/README.txt](https://github.com/visualcjy/macpm/blob/main/packaging/README.txt) for details.
196
+
197
+ ## Development
198
+
199
+ ```sh
200
+ git clone https://github.com/visualcjy/macpm.git
201
+ cd macpm
202
+ python3 -m venv .venv
203
+ . .venv/bin/activate
204
+ python3 -m pip install -e .
205
+ python3 -m unittest discover -s tests -v
206
+ ```
207
+
208
+ Build source and wheel distributions:
209
+
210
+ ```sh
211
+ python3 -m pip install build twine
212
+ python3 -m build
213
+ python3 -m twine check dist/*
214
+ ```
215
+
216
+ Build standalone arm64 binaries (build machine needs Python + PyInstaller +
217
+ runtime dependencies; the output has no Python dependency):
218
+
219
+ ```sh
220
+ PYTHON=python3 packaging/build.sh
221
+ ```
222
+
223
+ Release steps are documented in [RELEASE.md](https://github.com/visualcjy/macpm/blob/main/RELEASE.md).
224
+
225
+ ## Troubleshooting
226
+
227
+ - **`macpm: command not found`** — add your Python user-base `bin` directory to
228
+ `PATH`, or run `python3 -m macpm`.
229
+ - **Power readings freeze on macOS 27** — some builds restrict unprivileged
230
+ `Energy Model` refreshes. CPU/GPU usage and frequency still work. Run
231
+ `macpm-dump` to inspect the raw values.
232
+ - **M5/Ultra values look wrong** — CPU tier/channel mapping is not complete;
233
+ see the compatibility table.
234
+ - **`macpm-sensors` shows nothing** — not every SMC key exists on every chip;
235
+ the reader only reports the keys that are present.
236
+
237
+ ## Changelog
238
+
239
+ See [CHANGELOG.md](https://github.com/visualcjy/macpm/blob/main/CHANGELOG.md). The 2.0 release removes the dependency on
240
+ `sudo`, `powermetrics` and temporary files.
241
+
242
+ ## Credits
243
+
244
+ - [asitop](https://github.com/tlkh/asitop) — original Python TUI this project
245
+ was forked from
246
+ - [macmon](https://github.com/vladkens/macmon) and
247
+ [Stats](https://github.com/exelban/stats) — IOReport/SMC reference
248
+ implementations
249
+ - The IOReport sample-delta and DVFS-table ideas follow those projects
250
+
251
+ ## License
252
+
253
+ MIT. See [LICENSE](https://github.com/visualcjy/macpm/blob/main/LICENSE).
macpm-2.0/README.md ADDED
@@ -0,0 +1,212 @@
1
+ # macpm
2
+
3
+ **Rootless performance monitoring CLI for Apple Silicon.**<br>
4
+ macpm 2.0 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, disk I/O and
13
+ 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
+ - Disk IOPS/throughput and network throughput
33
+ - Optional temperature/fan reader (`macpm-sensors`)
34
+ - Same terminal layout, colours, charts and key bindings as macpm 0.x
35
+
36
+ ## Install
37
+
38
+ Requirements: **Apple Silicon Mac**, **macOS 12+**, **Python 3.9+**.
39
+
40
+ ```sh
41
+ python3 -m pip install --upgrade macpm
42
+ ```
43
+
44
+ Then run:
45
+
46
+ ```sh
47
+ macpm
48
+ ```
49
+
50
+ There is **no `sudo macpm`** in 2.0. Running it with `sudo` still works, but it
51
+ is unnecessary and no longer recommended.
52
+
53
+ Prefer a standalone binary with no Python installation? See
54
+ [Standalone binaries](#standalone-binaries).
55
+
56
+ ## Usage
57
+
58
+ ```text
59
+ macpm [--interval INTERVAL] [--color COLOR] [--avg AVG] [--show_cores [BOOL]] [--version]
60
+ ```
61
+
62
+ | Option | Meaning |
63
+ |---|---|
64
+ | `--interval SECONDS` | Sampling and display interval (default `1`) |
65
+ | `--color 1-8` | Display colour (default `2`) |
66
+ | `--avg SECONDS` | Averaging window for power values (default `30`) |
67
+ | `--show_cores [BOOL]` | Start in the per-core view |
68
+ | `--version` | Print the version |
69
+
70
+ Keys:
71
+
72
+ ```text
73
+ q / ESC quit
74
+ ← / → change colour
75
+ 1 / 2 default view / per-core view
76
+ Ctrl+R reset peaks
77
+ ```
78
+
79
+ ## Colour themes
80
+
81
+ Pick one with `--color N`, or press ← / → while macpm is running. The default
82
+ is `2` (green).
83
+
84
+ | | |
85
+ |---|---|
86
+ | **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) |
87
+ | **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) |
88
+ | **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) |
89
+ | **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) |
90
+
91
+ ## Why no sudo?
92
+
93
+ macpm 0.x called `sudo powermetrics`. In 2.0 the sampler reads the underlying
94
+ counters directly. The data is not secret; the old `powermetrics` CLI simply
95
+ requires root and Apple's private entitlements.
96
+
97
+ | Metric | Source |
98
+ |---|---|
99
+ | CPU E/P load and frequency | IOReport `CPU Stats` performance states |
100
+ | Per-core load | IOReport `CPU Core Performance States` |
101
+ | GPU load and frequency | IOReport `GPU Stats` / `GPU Performance States` |
102
+ | CPU / GPU / ANE power | IOReport `Energy Model` |
103
+ | RAM / swap | `psutil` |
104
+ | Disk / network | `psutil` counters |
105
+ | Thermal throttle | `pmset -g therm` |
106
+ | SoC name / core counts | `sysctl` |
107
+ | GPU core count | `ioreg` `gpu-core-count` |
108
+
109
+ The DVFS frequency tables are parsed from the `pmgr` IORegistry node;
110
+ M1–M3 store Hz there, M4+ store kHz.
111
+
112
+ ## Temperatures and fans
113
+
114
+ The default TUI intentionally stays identical to macpm 0.x, which has no
115
+ temperature/fan panel. The standalone SMC reader is available as:
116
+
117
+ ```sh
118
+ macpm-sensors
119
+ macpm-sensors --json
120
+ ```
121
+
122
+ It reads `AppleSMC` through the IOKit user client (read-only, no root) and
123
+ reports the raw sensor keys present on the chip, fan RPM/min/max, and
124
+ `PSTR`/`PPBR` power rails. Fan **control** requires root and is not
125
+ implemented.
126
+
127
+ ## Compatibility
128
+
129
+ Tested on macOS 27.2 with an M3 Max. Behaviour depends more on the chip
130
+ generation than on the macOS version:
131
+
132
+ | Environment | Status |
133
+ |---|---|
134
+ | macOS 12–15, M1–M4 | Works |
135
+ | macOS 26, M1–M4 | Likely works |
136
+ | macOS 26, M5 / M5 Pro / Max | Partial: new CPU tier/channel names (`MCPU`/`SCPU`) and `acc-clusters` DVFS data are not fully handled |
137
+ | macOS 15/26, M1/M2 Ultra | Needs verification: multi-die complex channels may be `ECPU0/1` |
138
+ | macOS 27 | Works on the tested M3 Max; some 27 builds restrict unprivileged `Energy Model` refreshes |
139
+ | Intel Macs | Not supported; the Apple-Silicon IOReport groups are absent |
140
+
141
+ ## Standalone binaries
142
+
143
+ Standalone unsigned/ad-hoc arm64 binaries (`macpm`, `macpm-sensors`) can be
144
+ built with `packaging/build.sh` and attached to a GitHub release. They bundle
145
+ Python and all dependencies, so the target Mac needs no Python installation.
146
+
147
+ On first launch from a browser download, macOS Gatekeeper may ask you to
148
+ right-click → Open, or you can remove the quarantine flag:
149
+
150
+ ```sh
151
+ xattr -d com.apple.quarantine ./macpm ./macpm-sensors ./macpm.command
152
+ ```
153
+
154
+ See [packaging/README.txt](https://github.com/visualcjy/macpm/blob/main/packaging/README.txt) for details.
155
+
156
+ ## Development
157
+
158
+ ```sh
159
+ git clone https://github.com/visualcjy/macpm.git
160
+ cd macpm
161
+ python3 -m venv .venv
162
+ . .venv/bin/activate
163
+ python3 -m pip install -e .
164
+ python3 -m unittest discover -s tests -v
165
+ ```
166
+
167
+ Build source and wheel distributions:
168
+
169
+ ```sh
170
+ python3 -m pip install build twine
171
+ python3 -m build
172
+ python3 -m twine check dist/*
173
+ ```
174
+
175
+ Build standalone arm64 binaries (build machine needs Python + PyInstaller +
176
+ runtime dependencies; the output has no Python dependency):
177
+
178
+ ```sh
179
+ PYTHON=python3 packaging/build.sh
180
+ ```
181
+
182
+ Release steps are documented in [RELEASE.md](https://github.com/visualcjy/macpm/blob/main/RELEASE.md).
183
+
184
+ ## Troubleshooting
185
+
186
+ - **`macpm: command not found`** — add your Python user-base `bin` directory to
187
+ `PATH`, or run `python3 -m macpm`.
188
+ - **Power readings freeze on macOS 27** — some builds restrict unprivileged
189
+ `Energy Model` refreshes. CPU/GPU usage and frequency still work. Run
190
+ `macpm-dump` to inspect the raw values.
191
+ - **M5/Ultra values look wrong** — CPU tier/channel mapping is not complete;
192
+ see the compatibility table.
193
+ - **`macpm-sensors` shows nothing** — not every SMC key exists on every chip;
194
+ the reader only reports the keys that are present.
195
+
196
+ ## Changelog
197
+
198
+ See [CHANGELOG.md](https://github.com/visualcjy/macpm/blob/main/CHANGELOG.md). The 2.0 release removes the dependency on
199
+ `sudo`, `powermetrics` and temporary files.
200
+
201
+ ## Credits
202
+
203
+ - [asitop](https://github.com/tlkh/asitop) — original Python TUI this project
204
+ was forked from
205
+ - [macmon](https://github.com/vladkens/macmon) and
206
+ [Stats](https://github.com/exelban/stats) — IOReport/SMC reference
207
+ implementations
208
+ - The IOReport sample-delta and DVFS-table ideas follow those projects
209
+
210
+ ## License
211
+
212
+ MIT. See [LICENSE](https://github.com/visualcjy/macpm/blob/main/LICENSE).
macpm-2.0/RELEASE.md ADDED
@@ -0,0 +1,102 @@
1
+ # Releasing macpm 2.0
2
+
3
+ This checklist prepares a GitHub tag and a PyPI upload. It does not push or
4
+ publish anything by itself.
5
+
6
+ ## 1. Preconditions
7
+
8
+ - macOS Apple Silicon, Python 3.9+.
9
+ - Clean working tree (`git status`), all tests passing.
10
+ - Version is `2.0` in:
11
+ - `setup.py`
12
+ - `macpm/__init__.py`
13
+ - `macpm/macpm.py` (`version = 'macpm v2.0'`)
14
+ - `CHANGELOG.md` has the 2.0 entry.
15
+
16
+ ## 2. Test from source
17
+
18
+ ```sh
19
+ python3 -m venv .venv
20
+ . .venv/bin/activate
21
+ python3 -m pip install -e .
22
+ python3 -m unittest discover -s tests -v
23
+
24
+ macpm --help
25
+ macpm-dump # one sample per second, Ctrl+C to stop
26
+ macpm-sensors # temperatures/fans, optional
27
+ ```
28
+
29
+ ## 3. Build and validate PyPI artifacts
30
+
31
+ ```sh
32
+ python3 -m pip install --upgrade build twine
33
+ rm -rf dist build *.egg-info
34
+ python3 -m build
35
+ python3 -m twine check dist/*
36
+ ```
37
+
38
+ Test the wheel in a **clean** venv (this is the real "no source tree" test):
39
+
40
+ ```sh
41
+ python3 -m venv /tmp/macpm-wheel-test
42
+ /tmp/macpm-wheel-test/bin/pip install dist/macpm-2.0-py3-none-any.whl
43
+ /tmp/macpm-wheel-test/bin/macpm --help
44
+ /tmp/macpm-wheel-test/bin/macpm-dump # Ctrl+C
45
+ ```
46
+
47
+ ## 4. Publish to PyPI
48
+
49
+ Preferred: configure PyPI Trusted Publishing for this repository and the
50
+ `pypi` environment, then run the `Release` GitHub workflow on tag `v2.0`.
51
+
52
+ Manual alternative:
53
+
54
+ ```sh
55
+ # requires a PyPI API token in ~/.pypirc or TWINE_PASSWORD
56
+ python3 -m twine upload dist/macpm-2.0.tar.gz dist/macpm-2.0-py3-none-any.whl
57
+ ```
58
+
59
+ Then verify:
60
+
61
+ ```sh
62
+ python3 -m pip install --upgrade macpm==2.0
63
+ macpm --version
64
+ ```
65
+
66
+ ## 5. Publish to GitHub
67
+
68
+ ```sh
69
+ git add setup.py pyproject.toml MANIFEST.in README.md CHANGELOG.md RELEASE.md \
70
+ macpm packaging tests .github bin
71
+ git commit -m "Release macpm 2.0: rootless IOReport sampler"
72
+ git tag -a v2.0 -m "macpm 2.0"
73
+ git push origin main
74
+ git push origin v2.0
75
+ ```
76
+
77
+ The `Release` workflow builds the sdist/wheel, checks metadata and attaches
78
+ the artifacts to a GitHub release. The PyPI job is opt-in: set the repository
79
+ variable `PUBLISH_PYPI=true` (Settings → Secrets and variables → Actions →
80
+ Variables) to publish to PyPI via trusted publishing. Leaving it unset keeps
81
+ tag pushes to a GitHub release only.
82
+ If you prefer a manual release, create one from the tag and upload
83
+ `dist/*.whl`, `dist/*.tar.gz` and the standalone tarball.
84
+
85
+ ## 6. Standalone arm64 binaries (optional)
86
+
87
+ On an Apple Silicon build machine:
88
+
89
+ ```sh
90
+ PYTHON=python3 packaging/build.sh
91
+ ```
92
+
93
+ This produces:
94
+
95
+ ```text
96
+ dist/macpm-2.0-macos-arm64.tar.gz
97
+ ```
98
+
99
+ Attach it to the GitHub release. The binaries are ad-hoc signed, not
100
+ notarized; see `packaging/README.txt` for the Gatekeeper note. To notarize,
101
+ pass `CODESIGN_ID` to the build script and submit/staple the archive with
102
+ `notarytool`.
@@ -0,0 +1,3 @@
1
+ """macpm: rootless performance monitor for Apple Silicon."""
2
+
3
+ __version__ = "2.0"
@@ -0,0 +1,3 @@
1
+ from .macpm import main
2
+
3
+ main()
@@ -0,0 +1,21 @@
1
+ """Print rootless samples as JSON (debug helper, not part of the TUI)."""
2
+
3
+ import json
4
+ import time
5
+
6
+ from .sampler import Sampler
7
+
8
+
9
+ def main() -> None:
10
+ sampler = Sampler(1)
11
+ sampler.prime()
12
+ try:
13
+ for _ in range(3):
14
+ time.sleep(1)
15
+ print(json.dumps(sampler.sample(), indent=2, default=str))
16
+ finally:
17
+ sampler.close()
18
+
19
+
20
+ if __name__ == "__main__":
21
+ main()