Commit Graph
7 Commits
Author SHA1 Message Date
ARIA 930e56bd07 Clean up LSP diagnostics across backend and frontend
Backend (nvcurve/):
- hal/fans.py, hal/limits.py, hal/gpu.py: replace conditional pynvml
  imports with the established 'pynvml: Any = _pynvml_import' pattern
  (fixes ~50 'possibly unbound' errors); type the result dicts; guard
  query_interface() results; explicit uuid/pci-bus parsing (int, hex
  convention documented); modernize Optional[T] -> T | None
- cli.py: fix 'curve_state' possibly-unbound and snap_path None handling
  in cmd_setup; wrap unchecked int()/open()/makedirs() calls in
  try/except with clean CLI errors; add module logger for silent
  except-pass blocks; raise ... from exc; fix unused loop vars and
  set-comprehension
- hal/snapshot.py: filepath: str | None; wrap all file ops; sorted
  imports; remove unused CT_POINTS import
- daemon.py: extract 0o666 to _SOCKET_MODE constant (intentional for
  /run sockets) with nosemgrep
- server.py: nosemgrep for Python 3.7-compat false positive (project
  requires >= 3.12); log previously-swallowed exception
- profiles/native.py, profiles/apply.py: wrap file ops and int(k)
  profile-key parsing; sorted imports; modernize typing

Frontend (frontend/src):
- Add .js extensions to all relative imports (standard TS-ESM; Vite
  resolves .js -> .ts)
- React.FormEvent (deprecated in React 19 types) -> React.SubmitEvent
- catch (e: any) -> catch (e: unknown) + instanceof Error narrowing
- React-hooks: move ref writes from render into effects; convert
  viewport reset to render-phase state adjustment; split
  selectPoint(index, multi) into selectPoint + togglePoint (no flag
  argument); remove non-null assertion
- Static inline styles -> Tailwind classes (dynamic positioning/cursor
  styles kept)
- Remove non-standard 'container' option from scrollIntoView (browsers
  ignore unknown options) which had orphaned a @ts-expect-error
- Object.fromEntries for Map -> Record conversion

Tooling:
- .gitignore: ignore .codegraph/ local tool data

Verified: tsc --noEmit, vite production build, python imports, and
full LSP scan (0 errors/warnings in both projects).
2026-09-08 23:57:30 +02:00
ARIA d9260007d1 fix: fan settings persistence, profile indicator, and point removal
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.
2026-09-02 17:25:09 +02:00
ARIA da507d55bb feat: add Dashboard tab with live GPU overview
Add a new Dashboard tab as the default/first tab (Dashboard - Curve -
Performance - Fans) showing a full GPU overview.

Backend:
- New hal/dashboard.py: one-shot static GPU info via NVML (VBIOS, CUDA
  cores, compute capability, bus width, BAR1/CPU-accessible VRAM,
  Resizable BAR, PCIe max, max clocks, power limits, temp thresholds,
  persistence mode, fan count, serial, board part number, UUID).
  ROP count and VRAM type are best-effort from a per-model table since
  NVML does not expose them.
- New /api/dashboard endpoint.
- MonitoringSample gains live throttle_reasons (+label), PCIe link
  width/generation (downclocks when idle, so read per poll), and VRAM
  temp (from the MEMORY thermal sensor, if exposed).

Frontend:
- New Dashboard component: critical top row (throttling, voltage,
  GPU/VRAM temps), full live-monitor grid with sparklines, and a static
  GPU-information grid. Unavailable fields are omitted.
- useDashboard hook + DashboardInfo type + api.client dashboard().

Also: restrict CORS to localhost origins (end-anchored), make
_int_key_deltas fail closed on bad keys, and clean up lint blockers in
server.py/monitoring.py.
2026-09-02 16:56:47 +02:00
ARIA bbd692ea2e feat: multi-user authentication (dual mode)
Add optional login protection for the web UI/API, intended for shared
machines (e.g. AI servers). Dual mode: with no users configured the API
and web UI are open (as before); once at least one user exists, every
/api/* and /ws/* endpoint requires a valid session.

- bcrypt password hashing: passwords stored as $2b$ hashes in
  /etc/nvcurve/users.json (0600, root-owned); plaintext never persisted.
- 24-hour sessions: HttpOnly cookie for browsers, Authorization: Bearer
  token for CLI/scripts; in-memory, invalidated on server restart.
- Multi-user: multiple named accounts (no shared-password mode).
- New CLI: nvcurve user add|list|remove|set-password (root for mutating
  ops; password always prompted, never a CLI argument).
- New endpoints: GET /api/ping (public), /api/auth/status|login|logout|users.
- Web UI: sign-in screen when auth is enabled; status bar shows the
  signed-in user with sign-out; expired sessions (401) re-show sign-in.
- Brute-force lockout: 10 failed logins/IP within 5 min -> 15 min lockout.
- New dependency: bcrypt.

Also: LSP config (pyrightconfig.json) pointing at the project .venv, and
small error-handling cleanups in daemon.py/server.py.
2026-09-02 15:21:35 +02:00
ARIA 26afaeecfa Fix fan_mode type to match backend API ('auto' | 'curve') 2026-08-01 16:03:02 +02:00
ARIA 477c4becae feat: add fan curve control via temperature-based fan speed curves
- Backend HAL (hal/fans.py): NVML v2 fan read/set/reset with min/max queries
- Server endpoints: GET/POST /api/fans, POST /api/fans/reset, POST /api/fans/speed
- Background fan poller: reads GPU temp every 2s, interpolates fan speed from curve
- Profile integration: fan_curve field saved/applied, auto-restore on shutdown
- Frontend: FanCurveEditor (SVG chart with drag/add/delete points), FanMonitor sidebar
- App.tsx: three-tab layout (Curve, Performance, Fans)
- GaugeCard: optional history sparkline, Fan Mode card without sparkline
- fan_mode field populated as 'curve' or 'auto' in GET /api/fans
2026-08-01 15:59:39 +02:00
ARIA 024dcbceb0 nvcurve with some fixes and better limits 2026-05-09 15:05:29 +02:00