Adds an experimental power-cap mode using the undocumented RM ioctl
interface (based on panchovix's LACT PR #1205) to set power limits
below the VBIOS minimum (down to 30 W).
- hal/rm_power.py: RM ioctl power-cap read/write/reset + runtime probe
- limits.py: power_cap_mode (nvml/ioctl) with support detection
- config.py: persist power_cap_mode per GPU
- profiles: record/apply power_cap_mode
- server.py: POST /api/limits validates ioctl support (409 on failure)
- cli.py: profile save falls back to persisted mode
- client.py: power_cap_mode in Limits
- frontend: toggle + warning with panchovix attribution (LACT #1205)
- tests: test_rm_power.py (unit) + integration coverage
- Makefile: add test_rm_power.py to make test
Also includes automated linter reformatting (prettier, ruff, shellcheck,
isort, markdownlint) that the linter would apply anyway.
Address three fan-settings issues:
1. Profile view: show a fan icon next to a profile's name when it has a
saved fan curve, so it's clear which profiles carry custom fans.
2. Fan curve persistence: the active fan curve was in-memory only and lost
on every server restart. It is now persisted per-GPU in
/etc/nvcurve/config.json (fan_curves) and re-applied at server startup,
so an applied curve survives restarts. All fan-curve state changes route
through _activate_fan_curve/_deactivate_fan_curve helpers that keep the
persisted state in sync (apply, reset, and profile apply).
3. Point removal: the fan-curve remove button was nearly invisible. The
chart remove control is now always faintly visible with an X glyph, the
table remove button is larger with a tooltip, and a hint line explains
how to add/remove points.
Also includes a formatting pass over the two edited frontend files.