479189ee4e
rigdoctor update assumed a pip/venv install and ran 'python -m pip install', which fails on a .deb (system python has no pip; you can't pip-upgrade a dpkg package). Add updates.install_kind() (dpkg ownership / venv / source-checkout detection, cached) and route apply_update: pip self-updates in place; apt and source installs return guidance instead. CLI and the GUI Update button show the apt/git command. Adds tests/test_updates.py. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
604 lines
36 KiB
Markdown
604 lines
36 KiB
Markdown
# Changelog
|
||
|
||
All notable changes to RigDoctor are recorded here. Format follows
|
||
[Keep a Changelog](https://keepachangelog.com/); versioning is SemVer-style
|
||
(`MAJOR.MINOR.PATCH`, pre-1.0). `__version__` and `pyproject.toml` must match the git
|
||
release tag (so the auto-updater, D18, can compare versions).
|
||
|
||
## [0.37.1] - 2026-05-22
|
||
### Fixed
|
||
- **`rigdoctor update` now uses the right method for how RigDoctor was installed.** It detects
|
||
apt (`.deb`), pip (venv/`.run`), or source installs (`updates.install_kind()`); only pip
|
||
installs self-update in place. An apt install no longer fails with "No module named pip" —
|
||
it (and the GUI Update button) shows `sudo apt update && sudo apt install --only-upgrade
|
||
rigdoctor`; a source checkout points to `git pull`.
|
||
|
||
## [0.37.0] - 2026-05-22
|
||
### Added
|
||
- **Version footer** — a footer across the bottom of the window shows `RigDoctor v<version>` in
|
||
the bottom-right (moved out of the sidebar).
|
||
### Fixed
|
||
- **Pages scroll when content doesn't fit, and the window is no longer pinned to the tallest
|
||
page's height.** Long pages (Settings, Tuning, …) get a scrollbar when too tall — so controls
|
||
like Uninstall are always reachable — and the window can now be resized smaller than the screen
|
||
(min height dropped from "taller than the screen" to ~600px). Pages that manage their own
|
||
scroll/fill (Dashboard, System Health, Inventory, Share) are unchanged.
|
||
|
||
## [0.36.1] - 2026-05-22
|
||
### Fixed
|
||
- `rigdoctor gui` printed the wrong fix when PySide6 is missing — it suggested the non-existent
|
||
`python3-pyside6` package. Now it names the real split modules
|
||
(`python3-pyside6.qt{widgets,gui,websockets,svg}` + `python3-pyte`).
|
||
|
||
## [0.36.0] - 2026-05-22
|
||
### Fixed
|
||
- **`.deb` now installs all dependencies automatically — no manual tool install.** The previous
|
||
`Recommends: python3-pyside6` named a package that doesn't exist on Debian/Ubuntu (PySide6 is
|
||
split per module), so apt silently skipped it and the GUI wouldn't start. Now it Recommends the
|
||
actual modules the GUI imports — `python3-pyside6.qt{widgets,gui,websockets,svg}` + `python3-pyte`.
|
||
### Changed
|
||
- **`apt install rigdoctor` sets up the whole toolset.** The `.deb` also Recommends the optional
|
||
diagnostic/gaming tools (smartmontools, lm-sensors, dmidecode, pciutils, libnotify-bin,
|
||
libsecret-tools, gamemode, mangohud) so they install by default — users never hand-install
|
||
tools. `cpupower` is a Suggests (kernel-tied); `--no-install-recommends` still gives CLI-only.
|
||
|
||
## [0.35.0] - 2026-05-22
|
||
### Added
|
||
- **`.deb` package (M9 / D8)** — `packaging/make_deb.py` builds a `rigdoctor_<version>_all.deb`
|
||
(pure-Python, `Architecture: all`) via `dpkg-deb`: `Depends: python3`, with the GUI deps
|
||
(`python3-pyside6`, `python3-pyte`) as **Recommends** so `sudo apt install ./rigdoctor_*.deb`
|
||
gives the full app and `--no-install-recommends` gives CLI-only. Installs the package, both
|
||
launchers, the desktop entry, and the icon. CI (`release.yml`) builds it as a **release asset**
|
||
every release, and optionally publishes it to the Gitea **apt registry** (set a `REGISTRY_TOKEN`
|
||
secret) for `sudo apt install rigdoctor`. **M9 is now complete.**
|
||
|
||
## [0.34.0] - 2026-05-22
|
||
### Added
|
||
- **Event-based alerts (M8).** Beyond temperature + GPU-lost, RigDoctor now notifies on
|
||
**critical kernel events** — Xid (GPU error), out-of-memory kills, CPU machine-checks, PCIe
|
||
AER errors, and disk I/O errors — scanned from the kernel log every ~30s while monitoring and
|
||
fired one-shot (cooldown-gated, so no spam). A proactive warning the moment something goes
|
||
wrong, not just on a temperature threshold. Included whenever desktop notifications are on.
|
||
|
||
## [0.33.0] - 2026-05-22
|
||
### Added
|
||
- **AI explanations stream live.** "Explain with AI" now fills token-by-token as the model
|
||
generates (Ollama NDJSON + Claude SSE, both via stdlib `urllib`) instead of a multi-second
|
||
freeze, then re-renders the finished answer as Markdown. `core/ai.explain_stream()`.
|
||
|
||
## [0.32.0] - 2026-05-22
|
||
### Added
|
||
- **More for diagnostics & reports:**
|
||
- **`nvidia-smi -q` snapshot** — driver, throttle/clock-event reasons, clocks, power, temps,
|
||
PCIe link, ECC + retired pages (point-in-time at diagnostic time).
|
||
- **Display-server log** — auto-detected: `Xorg.0.log` on X11, or the compositor's user-journal
|
||
slice (gnome-shell/kwin/sway/gamescope) on Wayland.
|
||
- **Full system inventory** (M5 hardware/OS) is now included in each stored diagnostic and the
|
||
**Report** bundle — invaluable for larger/shared debugging.
|
||
These join the kernel log + coredump records in `syslogs.txt`/`inventory.*`, are saved per
|
||
diagnostic, included in the Report zip, and (logs) fed to the AI on "Explain".
|
||
|
||
## [0.31.0] - 2026-05-22
|
||
### Added
|
||
- **Diagnostics now collect session-scoped system logs** (`core/syslogs.py`): a kernel-log
|
||
slice (`journalctl -k` — Xid, OOM-killer, MCE, PCIe AER, thermal, hung tasks) and
|
||
**crashed-process records** (`coredumpctl` — which executable, signal, and when). They're saved
|
||
to the diagnostic directory (`syslogs.txt`), included in the **Report** bundle, and fed to the
|
||
AI on "Explain" alongside the game logs. Best-effort — degrades quietly if the tools are
|
||
missing or access is denied; scoped to the session window so it doesn't drag in old noise.
|
||
|
||
## [0.30.0] - 2026-05-22
|
||
### Added
|
||
- **Logging & report bundles (M15, D25)** — opt-in via one **Settings → Logging** toggle
|
||
(default off). When on: the app logs to a rotating `app.log`, and **each diagnostic is stored
|
||
in its own folder** (`~/.local/share/rigdoctor/diagnostics/<id>/`) with the capture log, a
|
||
structured `result.json`, a readable `report.txt`, a session-scoped game-log snapshot, and an
|
||
`ai/` record of every AI interaction — **the exact data sent, which model, and its reply**.
|
||
- **Report** — a button on the diagnostic dialog (and `rigdoctor bundle`) zips a diagnostic's
|
||
folder plus `app.log` into `~/.local/share/rigdoctor/reports/<id>.zip` for sharing. Everything
|
||
stays local; the zip only leaves your machine if you share it. Available only when logging is on.
|
||
|
||
## [0.29.0] - 2026-05-22
|
||
### Added
|
||
- **AI now resolves Steam app IDs from your library instead of guessing.** When app IDs appear
|
||
in the logs/findings, RigDoctor looks them up in your scanned games (`steam.appid_names()`) and
|
||
injects an "App IDs (resolved from your installed games)" glossary into the prompt — so the
|
||
model names games correctly (e.g. `2694490 = Path of Exile 2`) rather than hallucinating. Only
|
||
IDs it can resolve locally are listed; no network, no model "training" needed.
|
||
|
||
## [0.28.1] - 2026-05-22
|
||
### Fixed
|
||
- **AI explanations were misreading stale/benign logs.** Three fixes so the model analyses the
|
||
*actual* session: (1) the prompt now states the **real game name, capture duration, and
|
||
outcome** (clean vs. crash) so the model stops guessing the game from log paths; (2) game logs
|
||
are **scoped to the session window** (Steam-console lines filtered by timestamp; a stale
|
||
per-app Proton log from an earlier game is skipped); (3) the reference KB flags common
|
||
**benign** Steam/Proton lines (`libnvidia-ml.so.1` assertion, routine minidump uploads, "fork
|
||
without exec") so they aren't reported as the cause. The system prompt also forbids
|
||
Windows-only advice (no "run as administrator") and tells the model not to invent a problem
|
||
when the run was clean.
|
||
|
||
## [0.28.0] - 2026-05-22
|
||
### Added
|
||
- **AI explanations now include recent game logs.** When you press "Explain with AI" on a
|
||
diagnostic, RigDoctor also gathers recent **Proton** (`~/steam-<appid>.log`) and **Steam**
|
||
console logs (`core/gamelogs.py`, tail-read + size-bounded) and passes them to the model, so
|
||
it can correlate log errors with the sensor findings and pinpoint *when* something went wrong.
|
||
### Fixed
|
||
- The AI explanation popup now **renders Markdown** (headings, bold, lists) instead of showing
|
||
raw `###`/`**` — `QTextEdit.setMarkdown`, and the model is told to answer in Markdown.
|
||
|
||
## [0.27.1] - 2026-05-22
|
||
### Changed
|
||
- AI assistant: selecting **Ollama** now pre-fills the model field with **`qwen2.5:7b`** (a
|
||
strong 7B that fits an 8 GB GPU; our grounding makes a 7B sufficient). It won't overwrite a
|
||
model you've already entered, and you can change it freely.
|
||
|
||
## [0.27.0] - 2026-05-22
|
||
### Added
|
||
- **AI assistant (M14, D24)** — optional, **strictly opt-in, never automatic**. Explains your
|
||
diagnostics in plain language only when you press **"Explain with AI"** on the diagnostic
|
||
dialog (or run `rigdoctor ai explain`). You choose a provider explicitly (no default):
|
||
**Ollama** (local, private, no key) or **Claude** (Anthropic; key stored in the keyring, with
|
||
a consent prompt before any data is sent). Configure in **Settings → AI assistant**.
|
||
- Answers are **grounded**: RigDoctor passes the actual findings plus matched reference facts
|
||
from a curated knowledge base (`core/ai_knowledge.py` — exact keyword/code match, no
|
||
embeddings, stdlib only), so even a small local model gets the domain facts it needs. Stdlib
|
||
`urllib` only — no new core dependency. Output is advisory (D9).
|
||
- CLI: `rigdoctor ai status|test|explain`.
|
||
|
||
## [0.26.1] - 2026-05-22
|
||
### Fixed
|
||
- **Setup wizard contrast.** The **radio buttons** (Recording trigger) were unstyled, so the
|
||
selected option was invisible on the dark theme — now styled with a clear accent ring + dot.
|
||
Bundle **checkboxes** got explicit checked/disabled states, and stay selectable even when a
|
||
bundle is already installed (the page no longer looks dead when everything's present).
|
||
|
||
## [0.26.0] - 2026-05-22
|
||
### Added
|
||
- **Graphical setup wizard (M9).** A first-run GUI wizard (`gui/setup_wizard.py`) walks through:
|
||
environment summary → pick **dependency bundles** (Diagnostics / Monitoring / Gaming / Updates,
|
||
from the component catalog) → install the missing apt packages → choose the **recording
|
||
trigger** → a readiness summary. It shows automatically on first launch (until done), is
|
||
re-runnable from **Settings → Run setup wizard** or `rigdoctor-gui --setup`, and `install.sh`
|
||
launches it after a fresh install when a desktop session is present.
|
||
|
||
## [0.25.0] - 2026-05-22
|
||
### Changed
|
||
- **Share is now terminal-only (D23, amends D16).** The Share page is a single shared-terminal
|
||
experience: the host shares their shell, the guest watches and may type **only if the host
|
||
ticks "Allow the guest to type"** (otherwise read-only). The terminal is larger and either
|
||
side can pop it **full-screen** (Esc to exit).
|
||
### Removed
|
||
- The read-only **stats view** (live sensors/health/inventory over the relay) and the
|
||
`rigdoctor share serve` HTTP server — the shared terminal replaces them. (`core/share.py`
|
||
removed; the `share` CLI command is gone.)
|
||
|
||
## [0.24.0] - 2026-05-22
|
||
### Added
|
||
- **Shared terminal is now in color.** The terminal view renders pyte's per-cell foreground/
|
||
background, bold, and reverse, so the host's real shell keeps its theming — fish, `ls`,
|
||
`git`, prompts, etc. look the same as locally (the session already runs the host's `$SHELL`
|
||
with its config and `TERM=xterm-256color`; only the rendering was monochrome).
|
||
|
||
## [0.23.0] - 2026-05-22
|
||
### Added
|
||
- **Crash-logger trigger modes (M9 / D6)** via `systemd --user`, no root: **manual**,
|
||
**always-on** (a background service records continuously), and **game-launch** (auto-records
|
||
while a Steam game runs). Set it from **Settings → Recording trigger** or
|
||
`rigdoctor service mode <manual|always-on|game-launch>`; `rigdoctor service status` shows it.
|
||
`core/service.py` writes/enables the user units.
|
||
- **Zero-config game-launch watcher** (`core/watcher.py`, `rigdoctor watch`) — polls Steam's
|
||
RunningAppID and brackets a focused capture around the running game (the D12 fallback for users
|
||
who don't add the `wrap` launch option; the wrapper stays the precise primary path).
|
||
|
||
## [0.22.0] - 2026-05-22
|
||
### Added
|
||
- **M6 breadth.** Environment checks now also report **GPU PowerMizer** mode (NVIDIA, X — flags
|
||
Adaptive/Auto and suggests Prefer-Max-Performance), the **Wine** version, and the **Steam
|
||
client** version.
|
||
- **Non-Steam launchers.** Lutris (its SQLite library) and Heroic (Epic + GOG JSON stores) are
|
||
detected (`core/launchers.py`) and listed on the Games page and `rigdoctor games`, tagged by
|
||
launcher. You can Run Diagnostic on them too (records while you play; auto-launch stays
|
||
Steam-only).
|
||
### Notes
|
||
- The zero-config game watcher (D12 fallback) is deferred to the M9 trigger-mode work, where the
|
||
service integration lives.
|
||
|
||
## [0.21.0] - 2026-05-22
|
||
### Added
|
||
- **Live monitor TUI (M2).** `rigdoctor monitor` is now a proper **curses** dashboard:
|
||
current / session-min / session-max per sensor, grouped by subsystem, with temperature and
|
||
utilization **color bands** (and GPU-lost flagged red). `q` quits, `r` resets the session
|
||
min/max. Falls back to a plain full-screen redraw on a non-TTY (`--plain` forces it). The
|
||
terminal face of the same live data the GUI dashboard graphs. Completes the Monitoring bundle.
|
||
|
||
## [0.20.0] - 2026-05-22
|
||
### Changed
|
||
- **Reorganized navigation** into grouped sidebar sections — **Monitor** (Dashboard) ·
|
||
**Diagnose** (Games, Recordings, System Health, Tuning) · **System** (Inventory) · **App**
|
||
(Settings, Share) — so it's clear where to go.
|
||
- **Renames for clarity:** *Health → System Health* (it's the overall 7-day system scan, not
|
||
per-game), *Environment → Tuning* (gaming tunables + fixes), *Logs → Recordings*,
|
||
*Setup → Settings*.
|
||
- **Settings** absorbed **Notifications** (alerts) — app configuration (components/deps, alerts,
|
||
account access, uninstall) now lives in one page; Notifications is no longer a separate item.
|
||
- **Recordings** is now a hub: pick which captured log to view (always-on capture, last
|
||
diagnostic, or a preserved crash), **Analyze crash** in place, alongside the recorder controls.
|
||
|
||
## [0.19.0] - 2026-05-22
|
||
### Added
|
||
- **System-tray applet (M11, D13).** A tray icon whose menu shows live **CPU / GPU temp** and
|
||
**memory used/total**, a **status line** (Normal / Hot / GPU not responding), and is led by a
|
||
**Run Diagnostic** submenu (pick a detected game → the guided session), plus **Open dashboard**,
|
||
**Start/Stop recording**, **Snapshot (copy)**, and **Quit**. It reuses the dashboard's sample
|
||
stream (no extra sampling). With a tray present, **closing the window hides to the tray** (Quit
|
||
exits); `rigdoctor-gui --tray` starts hidden for autostart. Needs a tray host — on GNOME the
|
||
AppIndicator extension; degrades to a no-op if none is available. Completes the Desktop UI bundle.
|
||
- **GUI smoke tests**: construct `MainWindow` headless and exercise the tray, so a startup crash
|
||
fails the build (closes the gap that let the 0.18.0 import regression ship).
|
||
|
||
## [0.18.2] - 2026-05-22
|
||
### Fixed
|
||
- **GUI wouldn't start** (0.18.0 regression): the recording indicator used a wrong relative
|
||
import (`from .core` → `rigdoctor.gui.core`, which doesn't exist), crashing `MainWindow` on
|
||
launch. Corrected to `from ..core`.
|
||
|
||
## [0.18.1] - 2026-05-22
|
||
### Changed
|
||
- Recording badge: dropped the sample count (not useful at a glance) — it now shows just
|
||
**● Recording** + the game, plus a **⚠ GPU-lost** line if one is detected.
|
||
|
||
## [0.18.0] - 2026-05-22
|
||
### Added
|
||
- **Global recording indicator.** While a capture is running, the sidebar shows a red
|
||
**● Recording** badge on every page — with the **game** being captured and the live sample
|
||
count (and a GPU-lost flag if seen). It polls the recorder, so it reflects captures started
|
||
any way: manual `record`, a guided diagnostic, or the Steam launch wrapper.
|
||
|
||
## [0.17.0] - 2026-05-22
|
||
### Added
|
||
- **Inventory page is back in the GUI** (it was removed in 0.7.2 in favor of the CLI). Sidebar
|
||
**Inventory** → System / CPU / Firmware / Memory / GPU / Storage / Display as cards, with
|
||
**Copy Markdown** and **Save…** for pasting into forum/bug reports, and **Refresh**. Root-only
|
||
details (motherboard/BIOS/RAM modules via dmidecode) fill in after the launch password prompt.
|
||
Backed by the existing M5 `core/inventory.py` — the CLI `rigdoctor inventory` is unchanged.
|
||
|
||
## [0.16.0] - 2026-05-22
|
||
### Added
|
||
- **Automatic crash-capture via a Steam launch wrapper (M6/D12).** Set `rigdoctor wrap
|
||
%command%` as a game's Steam launch option (or in Lutris/Heroic's wrapper field) and RigDoctor
|
||
starts a focused, game-tagged capture when the game launches and stops it cleanly on exit — no
|
||
manual Run Diagnostic / Finish. A hard freeze leaves the capture unterminated, so it's flagged
|
||
as a crash next launch. The wrapper resolves the game name from Steam's `SteamAppId`, doesn't
|
||
disturb an existing capture, and returns the game's exit code. (`core/wrap.py`, `rigdoctor wrap`.)
|
||
- GUI **Auto-capture…** helper on the Games page: shows the exact launch-option line (absolute
|
||
path, copy button) and how to set it in Steam.
|
||
- Auto-capture preserves an unanalyzed crash (`diagnostic-crash.jsonl`) before starting a new
|
||
capture, so relaunching the game can't wipe a crash report you haven't seen yet.
|
||
### Fixed
|
||
- `docs/MODULES.md` status column was stale — M1, M3, M4, M5, M8, M10, and M13 are done and now
|
||
marked ✅ (only M2 and M11 remain not-started; M6/M9/M12 in progress).
|
||
|
||
## [0.15.0] - 2026-05-22
|
||
### Added
|
||
- **Hard-crash detection & recovery for the guided diagnostic.** If a focused capture ends
|
||
without a clean stop (the recorder never wrote `session-stop` and isn't running), RigDoctor
|
||
treats it as a likely hard freeze. On launch the **Games** page shows a warning banner —
|
||
*"Your last diagnostic for <game> ended unexpectedly…"* — with **Analyze crash** / **Dismiss**.
|
||
- **Deeper crash analysis.** *Analyze crash* combines the captured window (final readings before
|
||
the freeze + any GPU-lost event) with a focused scan of the **previous (crashed) boot's kernel
|
||
log** (`journalctl -k -b -1`: Xid/panic/OOM/MCE/AER/thermal) plus SMART/driver/persistence/
|
||
live-temp checks — the full "what happened" picture. `core/diagnostic.py` gains
|
||
`pending_crash()` / `analyze_crash()`; `health.check_previous_boot()` +
|
||
`run_health_checks(include_journal=False)` back it.
|
||
|
||
## [0.14.0] - 2026-05-22
|
||
### Changed
|
||
- **Dashboard headline tiles are now history trend graphs** instead of single-value gauges —
|
||
GPU temp, GPU load, CPU temp, and memory each plot their recent history (with the current
|
||
value, window min/max, and a dashed warning-threshold line), so you can see changes over time
|
||
rather than only the instantaneous reading. New `HistoryGraph` widget (QPainter, no new deps).
|
||
|
||
## [0.13.0] - 2026-05-22
|
||
### Added
|
||
- **Run Diagnostic now explains itself and can launch the game.** Clicking Run Diagnostic shows
|
||
what to do — *play the game, reproduce the crash, then Finish & analyze* (and that data
|
||
survives a hard freeze + reboot) — and offers **Launch game & start** (asks Steam to run it by
|
||
appid) or **Start without launching**. The recording banner now spells out the next step
|
||
instead of just showing a sample count.
|
||
### Fixed
|
||
- Button labels containing "&" (e.g. "Finish & analyze") rendered as "Finish _analyze" because
|
||
Qt treated the "&" as a keyboard mnemonic — now escaped so the ampersand shows literally.
|
||
|
||
## [0.12.0] - 2026-05-22
|
||
### Added
|
||
- **Guided diagnostic in the GUI.** Each game on the **Games** page now has a **Run Diagnostic**
|
||
button → a focused, game-tagged capture starts and a recording banner appears (live sample
|
||
count, GPU-lost indicator) with **Finish & analyze** / **Discard**. Finishing opens a results
|
||
dialog: the window-scoped capture summary (peak temps/power, events, last samples) plus the
|
||
health findings as cards. The banner persists/restores if you navigate away and back while a
|
||
capture is running. Shares `core/diagnostic.py` with the CLI (one flow, three front-ends).
|
||
|
||
## [0.11.0] - 2026-05-22
|
||
### Added
|
||
- **Guided diagnostic session (CLI) — the seed use case, end to end.** `rigdoctor diagnose
|
||
start --game "<name>"` runs a **focused crash-capture tagged with that game** (its own
|
||
diagnostic log, so the report is scoped to just that session), `diagnose status` shows
|
||
progress, and `diagnose finish` stops it and prints a combined report: the **capture
|
||
summary** (peak temps/power, GPU-lost events, last samples — M3) plus the **health findings**
|
||
(Xid/SMART/driver/etc. — M4). The game can be given by `--game` or `--appid` (resolved from
|
||
the Steam scan), and is recorded as a log event so it survives a crash + reboot.
|
||
- Shared orchestration lives in `core/diagnostic.py` (one callable for CLI/GUI/tray, per
|
||
ARCHITECTURE §7.1); the recorder/`record run` gained an optional `--game` tag.
|
||
|
||
## [0.10.2] - 2026-05-22
|
||
### Changed
|
||
- When an Environment **Apply**/**Install** fails, the status now shows the **real reason**
|
||
(cancelled at the password prompt vs. the system rejecting the change, e.g. a BIOS/kernel-
|
||
locked PCIe ASPM policy) instead of a vague "cancelled, or needs privileges".
|
||
|
||
## [0.10.1] - 2026-05-22
|
||
### Fixed
|
||
- **Environment-page contrast.** The combo-box **drop-down list** was rendering light-on-light
|
||
(the popup view is a separate widget the theme didn't cover) — now dark with readable text.
|
||
- The **Install / Apply** buttons on findings were hard to read (the accent fill didn't paint
|
||
reliably inside the finding cards, leaving dim dark-on-dark text). They're now an outlined
|
||
style — bright accent text on the dark card, filling accent on hover — readable regardless,
|
||
and given a minimum height so the row can't crush them.
|
||
|
||
## [0.10.0] - 2026-05-22
|
||
### Added
|
||
- **Actionable Environment page (M6) — install & apply, not just advice.** Findings that
|
||
recommend a tool or a setting are now one-click:
|
||
- **Install buttons** for GameMode, MangoHud, and cpupower (added to the M9 component catalog,
|
||
so they also appear on the **Setup** page with the existing installer).
|
||
- **Apply controls** for runtime-reversible tunables — a dropdown of the live options + Apply,
|
||
via a single pkexec prompt, no reboot: **CPU governor**, **NVIDIA persistence mode**,
|
||
**PCIe ASPM policy**, **vm.swappiness**, **Transparent HugePages** (`core/fixes.py`). The
|
||
chosen value is validated against the live options before anything runs.
|
||
- This is the consent-gated apply milestone D9 anticipated, scoped to safe settings (**D22**).
|
||
GRUB-based fixes and CPU mitigations stay suggestion-only; `rigdoctor gameenv` still prints
|
||
the exact commands for headless use.
|
||
### Changed
|
||
- The `Finding` model gained optional `action` (installable component) and `fix` (applyable
|
||
tunable) fields; the shared `finding_card` widget renders the matching control.
|
||
|
||
## [0.9.0] - 2026-05-22
|
||
### Added
|
||
- **Gaming environment checks (M6) — the evaluate-and-suggest engine.** A new read-only report
|
||
(D9) that flags system settings which hurt gaming stability/performance and gives the exact fix
|
||
command. Checks: **PCIe ASPM**, **NVIDIA persistence mode**, **CPU governor** (the three that
|
||
map to the seed-case GPU bus-drop / Xid 79), GameMode, MangoHud, `vm.swappiness`, shader disk
|
||
cache, Transparent HugePages, CPU mitigations, and installed Proton versions.
|
||
- **CLI:** `rigdoctor gameenv` (text or `--json`).
|
||
- **GUI:** a new **Environment** page (findings cards, auto-runs on open), reusing the M4
|
||
health-report card style via a shared `finding_card` widget.
|
||
### Fixed
|
||
- **Notification icon** now uses the RigDoctor icon (matching the app/dock) instead of a generic
|
||
stock icon — resolved from the installed icon theme, the bundled asset, then a stock fallback.
|
||
|
||
## [0.8.0] - 2026-05-22
|
||
### Added
|
||
- **Gaming environment checks (M6) — Steam game detection.** RigDoctor now finds your Steam
|
||
libraries (across multiple drives, via `libraryfolders.vdf`) and the games installed in each
|
||
(parsing `appmanifest_*.acf` — stdlib only, no Steam tooling needed). Runtimes, Proton builds,
|
||
and redistributables are filtered out.
|
||
- **Opt-in libraries:** detected libraries are listed with a per-library game count; you check
|
||
the ones to scan. Nothing is scanned until you pick a library.
|
||
- **Background scan on every launch:** the GUI rescans the selected libraries in the background
|
||
when it opens and flags games installed since the last scan with a **NEW** badge plus a count
|
||
on the **Games** sidebar item (cleared when you view the page). Results are cached
|
||
(`~/.local/state/rigdoctor/games.json`) so the list shows instantly.
|
||
- **CLI:** `rigdoctor games` lists detected games; `rigdoctor games libraries
|
||
[--enable PATH | --disable PATH | --all]` lists/selects libraries (headless-complete, D17).
|
||
- Config now supports list values (TOML arrays); `steam_libraries` records the selected libraries.
|
||
|
||
## [0.7.3] - 2026-05-21
|
||
### Fixed
|
||
- Shared terminal now has **scrollback** — large output (e.g. `ls -la`) can be scrolled up to
|
||
read; it keeps a history buffer and only auto-scrolls to the bottom when you're already there.
|
||
|
||
## [0.7.2] - 2026-05-21
|
||
### Changed
|
||
- Removed the GUI **Inventory** tab — use the CLI `rigdoctor inventory` instead. (Inventory is
|
||
still collected for the relay guest view, so a remote helper still sees the host's hardware.)
|
||
### Fixed
|
||
- Shared terminal caret now sits at the real cursor position (row **and** column) instead of
|
||
the start of the line.
|
||
|
||
## [0.7.1] - 2026-05-21
|
||
### Fixed
|
||
- Shared terminal: a guest who joined **after** the host enabled the terminal stayed read-only.
|
||
The host now re-sends the terminal state when a guest joins, so the terminal is available.
|
||
- Inventory page no longer jumps back to the top when it refreshes (e.g. when elevated data
|
||
arrives) — scroll position is preserved and unchanged data isn't re-rendered.
|
||
- Shared terminal now follows the cursor to the bottom as output arrives (e.g. `ls -la`),
|
||
instead of staying scrolled up.
|
||
|
||
## [0.7.0] - 2026-05-21
|
||
### Added
|
||
- **Shared terminal (M12, Tier 3)**: when the host enables it, the session shares a real **PTY**
|
||
shell — the guest gets an interactive terminal (vim, top, tab-completion, Ctrl-C) running on
|
||
the host as the host's user. The host **reads along** live and can type too, e.g. a `sudo`
|
||
password — which stays local and is never sent to the guest. Off by default, host-consented.
|
||
The guest also pulls the host's inventory on join.
|
||
### Fixed
|
||
- **Input contrast**: all form controls (text fields, spin boxes, combo boxes, terminals) now
|
||
use the dark theme with readable text (Fusion defaulted them to light-on-light).
|
||
|
||
## [0.6.0] - 2026-05-21
|
||
### Added
|
||
- **Session sharing over the relay (M12)**: a **Share** tab — *Start shared session* (host)
|
||
hands you a short code and streams a read-only live view; *Enter share code* (guest) joins
|
||
someone else's session and views their sensors/health/inventory. Both connect outbound over
|
||
WebSocket to the relay (`relay_url`, default `wss://rigdoctor.jesseyvanofferen.com`), gated
|
||
by your Gitea access token — no port forwarding. Read-only.
|
||
|
||
## [0.5.0] - 2026-05-21
|
||
### Added
|
||
- **Session sharing (M12, Tier 2)**: `rigdoctor share serve` starts a **read-only** live view
|
||
(sensors auto-refresh + health report + inventory) over a local HTTP server, gated by a
|
||
random share token. Bind to localhost for local testing, or to all interfaces behind a
|
||
user-chosen tunnel (Tailscale/cloudflared/SSH) for remote help. No actions, no terminal.
|
||
(Tier 1 export and Tier 3 gated terminal still to come — D16.)
|
||
|
||
## [0.4.1] - 2026-05-21
|
||
### Fixed
|
||
- Checkbox contrast: a checked checkbox is now a clear accent-filled box with a checkmark
|
||
(was hard to tell checked from unchecked on the dark theme).
|
||
|
||
## [0.4.0] - 2026-05-21
|
||
### Added
|
||
- **Alerts (M8)**: desktop notifications (via `notify-send`) for **overheat** (GPU/CPU past a
|
||
threshold), **GPU-lost** (nvidia-smi timeout), and a **new version available** (fired once
|
||
per version). Edge-triggered with a cooldown so it doesn't spam. Degrades gracefully if
|
||
`notify-send` isn't installed.
|
||
- **Notifications page**: configure alerts (enable/disable, GPU/CPU temperature thresholds)
|
||
with a "Send test" button; changes apply live and persist to `config.toml`.
|
||
- **App icon**: ships a RigDoctor icon and shows it in the dock/launcher. The GUI
|
||
**self-registers** the icon + `.desktop` on launch (and sets the Wayland app-id), so a
|
||
self-update + relaunch picks it up — no need to re-run the installer.
|
||
|
||
## [0.3.2] - 2026-05-21
|
||
### Changed
|
||
- Replaced the per-page "Run with admin" buttons with a **single password prompt at launch**
|
||
(`pkexec`): the GUI collects root-only data (SMART + dmidecode board/BIOS/RAM) once and
|
||
caches it for the session, so Health and Inventory always show the full picture. Falls back
|
||
to non-root if cancelled/unavailable; disable via `elevate_on_launch = false`.
|
||
|
||
## [0.3.1] - 2026-05-21
|
||
### Fixed
|
||
- Changelog/release notes now **render Markdown** instead of showing raw `#`/`**` markup —
|
||
the in-app changelog uses `QTextEdit.setMarkdown()` and the update prompt renders notes as
|
||
rich text (closes #1).
|
||
|
||
## [0.3.0] - 2026-05-21
|
||
### Added
|
||
- **System inventory (M5)**: CPU, GPU (model/driver/VBIOS/VRAM/PCIe), motherboard/BIOS, RAM
|
||
(total + modules), storage, kernel, and display server. CLI `rigdoctor inventory`
|
||
(`--json` / `--markdown` / `--output`) and a GUI **Inventory** tab with Copy-as-Markdown,
|
||
Save, and "Run with admin" (for `dmidecode` board/BIOS/RAM details). Fills the last GUI tab.
|
||
|
||
## [0.2.0] - 2026-05-21
|
||
### Added
|
||
- **"Check for updates" button** in the sidebar — force an immediate version check instead of
|
||
waiting for the 30-minute poll.
|
||
|
||
## [0.1.1] - 2026-05-21
|
||
### Fixed
|
||
- Dialogs (the update prompt and changelog) were light-on-light and unreadable — they now use
|
||
the dark theme with readable text.
|
||
|
||
## [0.1.0] - 2026-05-21
|
||
_First milestone release — a complete, installable, self-updating RigDoctor: live monitoring,
|
||
crash capture + health report, desktop GUI, user-local install/uninstall, and updates._
|
||
### Added
|
||
- **In-app uninstaller**: "Uninstall RigDoctor" button on the Setup page (and
|
||
`rigdoctor uninstall [--purge]`) — removes the venv, launchers, and desktop entry, with an
|
||
option to also wipe settings/token/logs. Runs detached so it can delete its own venv.
|
||
- **In-app changelog**: a "Changelog" link in the sidebar opens the release history (tags +
|
||
notes) fetched from the update server.
|
||
|
||
## [0.0.10] - 2026-05-21
|
||
### Added
|
||
- **"Restart now" button** after a successful in-app update — relaunches RigDoctor for you
|
||
instead of asking you to restart manually.
|
||
- **Real release notes**: CI now sets each Gitea release's body from the matching CHANGELOG
|
||
section (instead of "Automated release for…"), and the updater shows **"What's new"** — a
|
||
notes dialog before applying (GUI) and in `rigdoctor update` (CLI).
|
||
### Changed
|
||
- Setup page / `rigdoctor install`: dropped internal module references (M4, M5, …) from the
|
||
component descriptions — end users don't need them.
|
||
- Adopting **Conventional Commits** + **git-cliff** (`cliff.toml`, `packaging/changelog.sh`)
|
||
to generate CHANGELOG entries from commit history going forward (D20).
|
||
### Fixed
|
||
- The self-extracting **`.run` installer** is now built **without makeself** (a pure-Python
|
||
self-extractor, `packaging/make_run.py`), so it reliably attaches to every release — it was
|
||
silently skipped before because the CI runner couldn't install makeself.
|
||
|
||
## [0.0.8] - 2026-05-21
|
||
### Added
|
||
- **Periodic update checks**: the GUI now re-checks for new releases while running (every
|
||
`update_check_minutes`, default 30; 0 disables), so a newly published version is detected
|
||
without restarting. After applying an update, re-checks stop until restart.
|
||
- **"Run with admin" on the Health page**: runs all checks (including root-only SMART) via
|
||
`pkexec rigdoctor report --json`, so the full report — not just "SMART needs root" — is
|
||
available from the UI.
|
||
|
||
## [0.0.7] - 2026-05-21
|
||
### Added
|
||
- **User-local installer** `install.sh` (no root): creates a private venv, links
|
||
`rigdoctor`/`rigdoctor-gui` into `~/.local/bin`, and adds a desktop entry. Re-run to
|
||
upgrade; `--uninstall` to remove.
|
||
- **Self-extracting `.run` installer** via `packaging/make-run.sh` (makeself) — one
|
||
download-and-run executable bundling the wheel + `install.sh`; built and attached to each
|
||
release by CI.
|
||
- **Self-update apply (M13)**: `rigdoctor update` now installs the newer version via
|
||
authenticated pip (`rigdoctor[gui] @ git+https://oauth2:<token>@…@<tag>`); the GUI sidebar
|
||
"Update to v…" button applies it and prompts to restart. Token is scrubbed from output.
|
||
|
||
## [0.0.6] - 2026-05-21
|
||
### Added
|
||
- **Token-gated updates (M13)**: store a Gitea Personal Access Token, **encrypted in the OS
|
||
keyring** (Secret Service / GNOME Keyring via `secret-tool`) with a 0600-file fallback.
|
||
`rigdoctor login` / `logout` / `update [--check]`; GUI **Setup → Update access** panel
|
||
(token field, "Get a token", backend status) and sidebar states (connect / up-to-date /
|
||
"Update to v…" / access denied). Updates are gated to accounts on the Gitea server (D18).
|
||
- `libsecret-tools` added to the installer catalog (enables encrypted token storage).
|
||
### Changed
|
||
- D18 update mechanism revised from anonymous public HTTP to **authenticated HTTP (token)** —
|
||
the Gitea instance requires sign-in for all anonymous access.
|
||
|
||
## [0.0.5] - 2026-05-21
|
||
### Added
|
||
- **M9 installer (first cut)**: detects distro / package manager / GPU; a catalog of optional
|
||
components (smartmontools, lm-sensors, dmidecode, pciutils, libnotify) with what each
|
||
enables; `rigdoctor install [--check] [-y]` installs missing apt packages via pkexec/sudo
|
||
with consent; GUI **Setup** tab with one-click install. Fixes the "smartmontools missing"
|
||
gap in the health report.
|
||
- **Update check (M13, check half)**: on GUI launch the sidebar checks the Gitea releases API
|
||
and shows "up-to-date", an "Update to v…" button if a newer release exists, or "update check
|
||
unavailable" if the API can't be reached anonymously.
|
||
|
||
## [0.0.4] - 2026-05-21
|
||
### Added
|
||
- **M4 health report**: scans kernel logs (NVIDIA Xid incl. 79 "fell off the bus", kernel
|
||
panic, OOM, MCE, PCIe AER, thermal, amdgpu reset), SMART health, NVIDIA driver/library
|
||
mismatch, journald persistence, and live temps → prioritized plain-language findings with
|
||
suggested fixes (read-only, D9).
|
||
- CLI `rigdoctor report` (text + `--json`).
|
||
- GUI **Health** tab: runs checks in the background; findings shown as severity-colored cards.
|
||
- Tests for the journal scanner.
|
||
|
||
## [0.0.3] - 2026-05-21
|
||
### Added
|
||
- Show the app version (`v<version>`) in the GUI sidebar.
|
||
|
||
## [0.0.2] - 2026-05-21
|
||
### Added
|
||
- **M3 crash-capture logger**: crash-safe JSONL (`fsync` per sample), size-based rotation,
|
||
GPU-lost/recovered event markers, atomic status file; `rigdoctor record run|start|stop|
|
||
status|report` (foreground `run` is the systemd-ready entrypoint).
|
||
- **GUI Recording/Logs page** (M10): start/stop/interval controls, live status, and the
|
||
post-crash report — driving the same recorder via shared `core.reccontrol`.
|
||
- Shared render helpers (`format_raw`, `format_headline`, `render_summary`) used by CLI + GUI.
|
||
- Tests for the crash log (writer, rotation, reader, summary, recorder).
|
||
- **Gitea Actions release workflow** (`.gitea/workflows/release.yml`): on push to `main`,
|
||
builds wheel + sdist and publishes a Gitea release `v<version>` with the artifacts.
|
||
### Changed
|
||
- **GUI-first** emphasis (D17): docs reframed; the CLI keeps full parity for headless/SSH.
|
||
- CPU core temperatures ordered (package, then core 0, 4, 8, …) at the source — fixes the
|
||
CLI ordering too.
|
||
- Distribution revised (D8): **user-local self-updating install** is primary, `.deb` optional.
|
||
### Planned (docs only)
|
||
- M12 session sharing / remote assist (D16); M13 no-root auto-update from the public repo
|
||
(D18); versioning/changelog convention (D19).
|
||
|
||
## [0.0.1] - 2026-05-21
|
||
### Added
|
||
- Initial release: planning docs and decisions (D1–D15); **M1 sensor core** (NVIDIA GPU via
|
||
nvidia-smi, CPU via hwmon, memory + DDR5 SPD temps, NVMe); CLI (`snapshot`, `monitor`,
|
||
`sources`); and the **M10 desktop GUI** — dark dashboard with circular gauges and
|
||
collapsible, temperature-colored cards.
|