feat: hook reliability, hook-errors setting, sparse config, and logging

Hook reliability:
- Add hook-errors = "warn" | "fail" setting (default: warn); in fail
  mode, abort launch when pre-launch hook exits nonzero or can't execute
- Ensure post-launch hook runs unconditionally, even when execute_wait()
  fails to spawn the game
- Propagate game's real exit status via std::process::exit(); report
  post-hook failures clearly to stderr
- Centralize hook execution via run_hook() helper (sh -c)

New features in this batch:
- Sparse config and profile support: only configured fields are written;
  unset fields fall back through profile → global chain
- config show --effective flag: renders the fully-resolved view
- Config migration: upgrades legacy flat config to current schema
- Structured decision logging (src/log.rs) for session-level audit trail
- Gamescope improvements: additional flags and validation
- CHANGELOG.md tracking template releases

Schema / UX:
- HookErrors enum (Warn/Fail) added to Settings and ResolvedSettings
- hook-errors key in keys.rs, mod.rs rendering, completion candidates,
  doctor output, help text, README, and dry-run display
- 9 focused tests covering warn/fail behavior, exit propagation,
  round-trip (set/show/reset), profile round-trip, export/import

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
2026-06-14 09:35:24 -04:00
parent a2364b1692
commit f984acf0e3
21 changed files with 4070 additions and 1105 deletions
+39 -22
View File
@@ -19,10 +19,10 @@ gamewrap %command%
## Features
- Short Steam launch options
- Friendly setting names like `overlay` and `performance`
- Friendly setting names like `mangohud` and `gamemode`
- Persistent config outside the Steam UI
- Named profiles for reusable setups
- Profile inheritance for layered setups
- Flat game-specific profiles layered on global defaults
- Game-specific profile binding through `game bind`
- Quick access to the last played game through `gamewrap last`
- Play time and launch count tracking per game
@@ -32,7 +32,6 @@ gamewrap %command%
- Config export/import for backup and sharing
- Direct config editing through `config edit`
- Profile export/import for sharing one setup at a time
- Profile tree view for inheritance checks
- Per-profile environment variable overrides
- gamescope Wayland compositor integration
- FPS cap through MangoHud
@@ -97,13 +96,13 @@ $HOME/.cargo/bin/gamewrap %command%
2. Turn MangoHud on by default:
```bash
gamewrap config set overlay on
gamewrap config set mangohud on
```
3. Turn GameMode on by default:
```bash
gamewrap config set performance on
gamewrap config set gamemode on
```
4. Check your setup before launching a real game:
@@ -133,13 +132,11 @@ gamewrap profile create benchmark
gamewrap game bind "Game.exe" benchmark
```
8. Layer one profile on top of another when you want shared defaults:
8. Add game-specific overrides while keeping shared values global:
```bash
gamewrap profile create base
gamewrap profile set base overlay on
gamewrap config set mangohud on
gamewrap profile create benchmark
gamewrap profile inherit benchmark base
gamewrap profile set benchmark verbose on
```
@@ -181,6 +178,8 @@ gamewrap run -- /path/to/game/executable
```bash
gamewrap --help
gamewrap help settings
gamewrap help settings gamescope
gamewrap help settings mangohud
gamewrap help doctor
gamewrap game list
gamewrap game list "elden"
@@ -196,20 +195,23 @@ gamewrap completion zsh
gamewrap completion install zsh
gamewrap completion path zsh
gamewrap config show
gamewrap config show --effective
gamewrap config edit
gamewrap config reset --all
gamewrap config migrate
gamewrap config export shared
gamewrap config import shared
gamewrap last
gamewrap profile list
gamewrap profile tree
gamewrap profile create benchmark
gamewrap profile show benchmark
gamewrap profile show benchmark --effective
gamewrap profile duplicate benchmark benchmark-copy
gamewrap profile inherit benchmark base
gamewrap profile clear-inherit benchmark
gamewrap profile export benchmark benchmark
gamewrap profile import benchmark
gamewrap profile set benchmark overlay on
gamewrap profile reset benchmark overlay
gamewrap profile migrate old-benchmark
gamewrap profile set benchmark mangohud on
gamewrap profile reset benchmark mangohud
gamewrap profile env set benchmark DXVK_ASYNC 1
gamewrap profile env list benchmark
gamewrap profile env unset benchmark DXVK_ASYNC
@@ -222,15 +224,20 @@ gamewrap game clear-note "eldenring.exe"
## Friendly Settings
- `overlay`: turns MangoHud on or off
- `performance`: turns GameMode on or off
- `mangohud`: turns MangoHud on or off
- `gamemode`: turns GameMode on or off
- `steam-host-libs`: prefers host libraries inside Steam runtime environments and sets `STEAM_RUNTIME_PREFER_HOST_LIBRARIES=1`
- `game-libs`: controls whether `gamewrap` injects auto-detected host library directories into `LD_LIBRARY_PATH`
- `verbose`: shows more detail in diagnostic commands
- `log-file`, `log-path`: append gamewrap launch decisions to the default state log or a custom path
- `gamescope`: wraps the game in the gamescope Wayland compositor
- `gamescope-width`, `gamescope-height`, `gamescope-fps`: pass `-W`, `-H`, and `-r` values to gamescope when `gamescope` is on
- `fps-cap`: caps frame rate through MangoHud when `overlay` is on, for example `gamewrap config set fps-cap 60`
- `gamescope-width`, `gamescope-height`: set output resolution with a pixel count or `native`; unset uses gamescope's 1280x720 default
- `gamescope-mode`: selects `windowed`, `borderless`, or `fullscreen`
- `gamescope-fps`: passes the `-r` target refresh value when gamescope is on
- `fps-cap`: caps frame rate through MangoHud when `mangohud` is on, for example `gamewrap config set fps-cap 60`
- `mangohud-log`, `mangohud-log-path`: enable full-session MangoHud performance logging and optionally choose its output path
- `vkbasalt`: enables vkBasalt post-processing with `ENABLE_VKBASALT=1`
- `vkbasalt-log-level`: sets `VKBASALT_LOG_LEVEL` to `debug`, `info`, `warning`, `error`, or `none` when vkBasalt is on
- `esync`: forces Proton esync on or off with `PROTON_NO_ESYNC`; leave unset to use Steam/Proton defaults
- `fsync`: forces Proton fsync on or off with `PROTON_NO_FSYNC`; leave unset to use Steam/Proton defaults
- `large-address-aware` / `laa`: sets `PROTON_LARGE_ADDRESS_AWARE=1` for older 32-bit Proton games that need more than 2 GB of address space
@@ -238,9 +245,20 @@ gamewrap game clear-note "eldenring.exe"
- `post-launch`: runs a shell command after the game exits; when set, gamewrap spawns the game and waits for it to finish before running this hook
- `env-vars`: per-profile environment overrides managed with `gamewrap profile env set/list/unset/clear`
**hook-errors** (`warn` | `fail`, default: `warn`)
Controls what happens when a pre-launch hook exits nonzero or cannot be executed.
- `warn` — a message is printed to stderr and the game launches anyway.
- `fail` — gamewrap aborts with an error and the game is not launched.
The post-launch hook always runs after the pre-launch hook succeeds, even if the game itself fails to start.
Example:
gamewrap config set hook-errors fail
## How It Works
When `gamewrap` launches a game, it resolves your defaults, any inherited profile chain, and any matching game binding, prepares the needed environment variables, and then prefixes the game command with `gamescope`, `mangohud`, and/or `gamemoderun` when those features are enabled.
When `gamewrap` launches a game, it applies global defaults, then any matching profile overrides, prepares the needed environment variables, and prefixes the game command with `gamescope`, `mangohud`, and/or `gamemoderun` when those features are enabled.
If something important is missing, `gamewrap` is designed to fail clearly instead of silently skipping the requested behavior. The `doctor` and `status` commands help you verify that before launching through Steam.
@@ -253,7 +271,6 @@ For terminal usage, `gamewrap` distinguishes between management commands and exp
- `gamewrap config edit` opens the config file in `$VISUAL`, `$EDITOR`, or `nano`
- use `gamewrap config export` and `gamewrap config import ...` for full-config backup and sharing
- use `gamewrap profile export` and `gamewrap profile import ...` for sharing one profile
- use `gamewrap profile tree` to inspect profile inheritance
- use `gamewrap profile env set <profile> <KEY> <VALUE>` for per-profile environment overrides
- use `gamewrap notify test` to verify graphical failure notifications
- use `gamewrap run <command>` when you want to explicitly launch from the terminal
@@ -302,9 +319,9 @@ gamewrap profile import benchmark
`gamewrap` automatically adds `.gamewrap.toml` or `.gamewrap-profile.toml` when needed.
`gamewrap config export` writes resolved settings, not just the sparse internal overrides. That makes the exported file more predictable when you import it on another machine with different defaults.
`gamewrap config export` writes the sparse global defaults and profile overrides exactly as configured.
`gamewrap profile export` also writes resolved settings. Imported profiles are brought in as standalone profiles with explicit values, so they keep the same behavior even if the importing machine uses different defaults.
`gamewrap profile export` writes only explicitly configured profile settings. Imported profiles use the receiving machine's global defaults for every unset value.
## Files