Repository navigation
Releases: open-nexa/cpum
Release list
CPU Manager v0.2.0
A "people can actually find and install it" release, plus the performance pass that came out of profiling the metrics pipeline.
The feature set is the one 0.1.0 shipped. What changed is how reachable it is, how honest the numbers in it are, and how much work the app does per second to show you the same table.
📥 Download page — links are read from the releases API, never built from a filename template.
| Architecture | Installer |
|---|---|
| x64 | CPU-Manager_v0.2.0_windows-x64-setup.exe |
| ARM64 | CPU-Manager_v0.2.0_windows-arm64-setup.exe |
Also published: .sig signatures, updater archives (.nsis.zip + .sig), latest.json, and SHA256SUMS.txt. Per-user NSIS install into %LOCALAPPDATA% — no UAC prompt. The app always runs un-elevated; only service management asks for admin rights.
⚠️ Read before upgrading from 0.1.x
- The bundle identifier is now
com.open-nexa.cpum, so the data directory moved from%APPDATA%\com.eason.cpumto%APPDATA%\com.open-nexa.cpum.affinity_rules.jsonmigrates automatically on first start. Installers built before the identifier change cannot be upgraded in place — uninstall the old version first, then install 0.2.0. Your rules move with you. - The updater endpoint now points at
open-nexa/cpum. Installations of 0.1.1 and older checkyixinin/cpumand will not see this release. Install 0.2.0 by hand once; every later version arrives through the in-app updater. - The 5-second service poll, the 1-second metrics cadence, the rule schema and the ProBalance journal format are unchanged.
Verify your download:
Get-FileHash .\CPU-Manager_v0.2.0_windows-x64-setup.exe -Algorithm SHA256Compare with the matching line in SHA256SUMS.txt.
Highlights
Reaching people
- A download page at open-nexa.github.io/cpum, published from
docs/releases/. Every link comes from the releases API and is classified in code, so a renamed artifact cannot turn into a 404. Cached inlocalStoragewith a committed snapshot for when the API is rate-limited. - An
Installsection in both READMEs — both architectures,SHA256SUMS.txtverification, and the SmartScreen warning an unsigned installer produces. Until now neither README said where the installer comes from. - Screenshots in both READMEs — flat and tree process view, rule manager, ProBalance panel — plus
screenshots/README.mdso the next set stays consistent. docs/ROADMAP.md— what is solid, what is not, the next four phases, and a non-goals section with the reason for each one. Written to be argued with.- Contributing surface:
CONTRIBUTING.md,SECURITY.md,CODE_OF_CONDUCT.md, issue/PR templates, Dependabot, CodeQL and gitleaks.
Performance
Profiled end to end and fixed where the measurement said so — full write-up in docs/PERFORMANCE-FIX-PLAN.md.
- The process table is virtual-scrolled.
v-data-tableran withitems-per-page="-1", so every row was live in the DOM and every metrics tick patched all ~390 of them while only ~20 were on screen. The newProcessTable.vuerenders the viewport plus an overscan — 390 rows of input produce 22 rendered rows. Columns, tree indentation, right-click menu, priority colours and per-CCD affinity swatches are unchanged. - Applying a rule no longer rewrites what is already correct. The service used to rewrite affinity and all three priority classes for every matching process every five seconds, and each write makes the kernel re-evaluate thread placement for every thread in the process. It now reads the current state first and skips the write when it already matches. A process whose state cannot be read is still written every time, so this can only cost less — never stop a rule from being enforced.
- Fewer syscalls per round. Network counters reuse the handle the sampler already holds instead of opening a second one (which also asked for
PROCESS_QUERY_INFORMATIONmore often than it was granted — so the network column now populates for more processes, not just faster). The per-process walk is single-threaded below 600 processes, where spawning threads measured slower than the work itself (11.3 ms with 8 threads vs 10.1 ms single-threaded). Exe path and priority classes are cached on PID + creation time, so a recycled PID cannot inherit another process's values. - One front-end timer instead of two — the ProBalance panel no longer runs its own 2 s poll.
Correctness
- Four CSS rules that never applied.
App.vueused:deep(.v-main),:deep(.v-container)and two:deep(.v-data-table …)rules in a non-scoped<style>block. Vue only rewrites:deep()inside a scoped block, so they matched nothing — the viewport height constraint and the table's fixed-column/ellipsis rules had been inert since they were written. Invisible under Vite 6's esbuild, reported by Vite 8's lightningcss. - Tree mode kept its children. Rows were sorted globally, so a child with higher CPU than its parent moved away while keeping the parent's indentation — expanding the parent no longer revealed its subtree.
- Narrow windows can reach the right-hand columns — the table body scrolls horizontally with the header.
- "Applied to N processes" no longer under-reports. Processes the elevated service found already correct were returned as skipped rather than writes and vanished from the count.
get_process_group_maskscould half-read a process. Affinity is the union over threads, so a mask built from some of them can equal a rule's masks while unobserved threads run elsewhere — which made the idempotent apply skip a needed write. Now all-or-nothing: any unreadable thread returnsNoneand the caller writes.(0, 0)is not "unconstrained." Windows never reports a mask of 0, so a zero read now counts as unknown and takes the write path.- The 2 s priority cache was keyed on PID alone, so a recycled PID could be served its predecessor's priorities. It now stores creation time, like the exe-path cache already did.
- The CI NSIS bundle step could not fail for a real reason — it passed its updater override as backslash-escaped inline JSON, which is right for bash and wrong for PowerShell, the default shell on
windows-latest. Now a file, so no shell is involved.
Dependencies
One branch instead of sixteen dependabot PRs: Vite 8.3, @vitejs/plugin-vue 6.0, vue-tsc 3.3, Vuetify 4.2, sass-embedded 1.105, TypeScript 6.0; tauri 2.12, tauri-build 2.7, tauri-plugin-opener 2.7, tauri-plugin-updater 2.13, uuid 1.27, windows-service 0.8; the GitHub Actions group bumped across all four workflows.
- TypeScript stops at 6.0, not 7.0 — 7.0 is the native (Go) compiler whose
exportsmap has no./lib/tsc, whichvue-tscrequires (ERR_PACKAGE_PATH_NOT_EXPORTED). - The Rust and JS halves of each Tauri package are pinned to the same version;
tauri buildrefuses to bundle when they differ on major/minor. - Security:
vue3.5.43 (GHSA-g2v6-rqmx-r4w6),source-map-js1.2.2 (GHSA-68fv-2mgg-jv7q),rustls0.23.45 (RUSTSEC-2026-0285).
Requirements
- Windows 10 or later (x64 or ARM64); WebView2 Runtime ships with current Windows.
- Windows 10 1803+ for soft rule mode (CPU Sets).
- Windows 11 24H2+ for per-process network I/O counters — older builds read zero.
- Administrator rights only for service install / uninstall / start / stop.
Known limitations
- Installers are still unsigned, so SmartScreen warns on first run. Code signing through SignPath Foundation is the last open item in Phase 0 of the roadmap; this costs more downloads than any missing feature.
- ProBalance is still experimental, labelled Unstable in the toolbar tooltip and as a chip next to the panel title. The heuristic works; the threshold defaults are guesses and there is no journal analysis tooling yet. It loses the label on evidence, not on optimism.
- ARM64 is built but not validated — same source, but CCD grouping and hybrid P/E-core classification have only been exercised on x64. That's Phase 1.
- The rule engine polls every five seconds rather than subscribing to process-creation events, so a process that starts, runs and exits between two ticks is never pinned.
- PPL processes (and some anti-cheat / AV processes) cannot be modified at any privilege level; the error is surfaced as-is.
- A few backend success messages are not localized yet, so an English sentence can occasionally appear in the Chinese UI.
Security
The desktop app runs un-elevated; only service management elevates, and the GUI reaches processes it cannot open through the service over a named pipe guarded by a per-user token, rather than raising a UAC prompt. Privilege boundary and private reporting: SECURITY.md.
📄 Full release notes: docs/releases/v0.2.0.md · 中文版 · CHANGELOG · Roadmap
What's Changed
- Apply the performance audit backlog by @yixinin in #22
- Virtual-scroll the process table by @yixinin in #23
- Upgrade dependencies in one branch instead of 16 dependabot PRs by @yixinin in #24
- Add v0.2.0 release notes and cut the changelog section by @yixinin in #25
New Contributors
- @yixinin made their first contribution in http...
v0.1.0
Full Changelog: https://github.com/open-nexa/cpum/commits/v0.1.0