ad46ad6b14
- Extract canonical date algorithm to src/date.rs; remove duplicates in log.rs and detect.rs - Extract build_std_command in launch.rs; unify needs_host_library_injection via pub(crate) delegation - Add missing unknown-setting warning to parse_imported_config in share.rs - Extract format_with_hint helper in error.rs; set_proton_no_sync helper in env.rs - Remove dead match in completion.rs shell_path_literal; use parse_fps for FpsCap in keys.rs - Replace six as_str() impls with impl_as_str! macro in schema.rs - Collapse ResolvedSettings::apply (~110 lines) with apply_scalar!/apply_opt!/apply_clone! macros - Replace six color functions with color_fn! macro in color.rs 89/89 tests passing, zero clippy warnings. Co-Authored-By: claude-flow <ruv@ruv.net>
13 KiB
13 KiB
PROJECT_MAP.md
Auto-generated project index. Update this file whenever you add, remove, or significantly change a file or feature.
Last updated: 2026-03-21 - reworked into a more operational map focused on edit paths, persistence contracts, and update triggers
🗺️ Project Overview
gamewrap is a Rust CLI for Linux/Steam users who want short Steam launch options while still applying MangoHud, GameMode, profile-based behavior, diagnostics, and shareable setup files. It uses clap for the CLI, TOML for persistence/share formats, and XDG config/state paths for local data.
🏗️ Architecture Summary
- Steam launch path: parse implicit Steam launch -> inspect real executable -> resolve defaults/profile/binding -> build env/wrapper plan -> exec target
- Management path: parse subcommand -> load config/state as needed -> mutate or render -> save TOML back to XDG paths
- Shell completion path: completion hook runs before normal CLI parsing and asks live config/state for dynamic candidates
Representative flow:
gamewrap %command% -> src/lib.rs -> src/cli.rs -> src/detect.rs -> src/profile.rs -> src/launch.rs -> src/env.rs -> exec
📁 File & Folder Map
| Path | Role | Notes |
|---|---|---|
Cargo.toml |
Crate manifest | Dependency and package metadata; clap_complete uses dynamic completion support. |
Cargo.lock |
Lockfile | Pinned dependency graph. |
README.md |
User docs | Install, command examples, sharing, completion, Steam usage. |
PROJECT_MAP.md |
Persistent project index | This file. Keep concise and tactical. |
docs/roadmap.md |
Deferred planning | Future integrations, packaging direction, product scope. |
src/main.rs |
Binary entry point | Converts AppError into stderr + notifier + exit code. |
src/lib.rs |
Library entry point | Runs completion hook first, then normal CLI parse/dispatch. |
src/cli.rs |
Command surface and dispatch | Owns top-level commands, parsing, command execution, and many user-facing error paths. |
src/color.rs |
Terminal color helpers | Enables ANSI styling only when NO_COLOR is unset and stdout is a TTY. |
src/completion.rs |
Completion engine | Generates/install shell scripts and dynamic candidates for settings, profiles, and observed games. |
src/config/mod.rs |
Config/state I/O | XDG path discovery, TOML load/save, CLI rendering of config/profile views. |
src/config/schema.rs |
Persistent structs | Settings, ResolvedSettings, ProfileConfig, ConfigFile, ObservedGame, StateFile. |
src/config/keys.rs |
Setting mutation helpers | Friendly key parsing and value application/reset logic. |
src/config/migrate.rs |
Config migration logic | Renames retired setting keys in raw config/profile TOML before typed deserialization. |
src/profile.rs |
Resolution + validation | Applies global defaults plus one named profile and validates binding targets. |
src/bindings.rs |
Binding operations | Matching logic, set/remove binding, resolve profile for executable/observed game. |
src/detect.rs |
Executable detection | Pulls real game executable out of Steam/Proton wrapper shapes and records observed launches. |
src/launch.rs |
Launch planning/execution | Dependency checks, dry-run rendering, final command execution. |
src/env.rs |
Env shaping | Steam-context detection, host-library injection decisions, env var construction. |
src/log.rs |
Decision log | Best-effort timestamped launch, hook, exit, and playtime logging. |
src/doctor.rs |
Doctor rendering | Formats preflight results. |
src/status.rs |
Status rendering | Formats dependency/config/state summary. |
src/help.rs |
Long-form help text | Shared topic help and top-level examples. |
src/error.rs |
Error model | Exit-code-bearing error categories and constructors. |
src/notify.rs |
GUI failure notifier | zenity / kdialog / xmessage / notify-send selection and popup logic. |
src/share.rs |
Share/import formats | Sparse full-config and single-profile portable TOML formats. |
tests/cli_matrix.rs |
Integration CLI coverage | End-to-end command validation in isolated XDG temp envs. |
Skip target/ and other generated artifacts when extending this map.
🧭 Hot Paths
Add or change a CLI command
- Edit:
src/cli.rs - Usually also update:
src/help.rs,README.md,tests/cli_matrix.rs - If command affects config/state formats:
src/config/schema.rs,src/share.rs, this map
Change config keys or setting behavior
- Edit:
src/config/keys.rs,src/config/schema.rs - Usually also update:
src/config/mod.rs,src/profile.rs,src/help.rs, completion candidates insrc/completion.rs, tests
Change profile behavior
- Edit:
src/profile.rs - Usually also update:
src/cli.rs,src/config/mod.rs,src/share.rs, tests
Change binding or game matching behavior
- Edit:
src/bindings.rs,src/detect.rs - Usually also update:
src/cli.rs,src/completion.rs, tests
Change launch/runtime behavior
- Edit:
src/launch.rs,src/env.rs - Usually also update:
src/doctor.rs,src/status.rs, help/docs, tests
Change shell completion behavior
- Edit:
src/completion.rs - Usually also update:
src/cli.rs,src/help.rs,README.md, tests
Change import/export/share behavior
- Edit:
src/share.rs - Usually also update:
src/cli.rs,README.md,src/help.rs, tests
🔑 Key Concepts & Domain Terms
- Defaults: global baseline settings from config
- Profile: reusable game-specific settings bundle applied directly over global defaults
- Binding: matcher string mapping a known executable/path to a profile
- Observed game: recorded launch entry with executable, path, last launched profile, optional note/display name, launch count, and last launch timestamp
- Resolved settings: effective values after applying global defaults + explicit profile overrides
- Steam context: environment where implicit launch mode and GUI failure notifications are enabled
- Share format: portable sparse export matching the internal defaults/profile layout
🔗 Persistence Contracts
Internal local files
- Config path:
~/.config/gamewrap/config.toml - State path:
~/.local/state/gamewrap/state.toml - Default decision log path:
~/.local/state/gamewrap/gamewrap.logwhenlog-fileis enabled - Config file is sparse/raw:
- stores only explicit overrides
- profiles may be empty and always apply directly over global defaults
- bindings are stored separately
- gamescope output width/height accept an integer or
native; window mode is one ofwindowed,borderless, orfullscreen
Portable share files
- Full config export suffix:
.gamewrap.toml - Profile export suffix:
.gamewrap-profile.toml - Export commands preserve sparse defaults and profile overrides
- Profile import preserves explicitly configured settings; unset values use the receiving config's global defaults
- Per-profile env overrides are stored as an optional
env-varsmap on profile settings and apply over global env defaults - Pre/post launch hook commands are stored as optional string settings; setting post-launch switches execution to spawn/wait so the hook can run after the game exits
- Config import accepts:
- current resolved share format
- legacy raw config format as fallback
🖥️ User-Facing Command Surface
Top-level commands
helpstatusdoctorrundry-runlastconfigprofilegamenotifycompletion
config
show [--effective]editset <setting> <value>reset <setting>/reset --allexport [name-or-path]import <name-or-path>migrate
profile
listcreate <name>duplicate <src> <dst>show <name>export <name> [name-or-path]import <name-or-path>migrate <file> [--dry-run]env set <name> <key> <value>env unset <name> <key>env list <name>env clear <name>set <name> <setting> <value>reset <name> <setting>delete <name>
game
list [matcher]show <matcher>bind <matcher> <profile>unbind <matcher>rename <matcher> <name>note <matcher> <text...>clear-note <matcher>forget <matcher>
notify
test
completion
<shell>prints the raw scriptinstall <shell>installs shell integrationpath <shell>shows where the script/startup wiring lives
🧪 Test Coverage Map
- Unit tests live inline in several
src/*modules - Integration coverage lives in
tests/cli_matrix.rs
If you change:
- command surface -> update
tests/cli_matrix.rs - share/import/export formats -> update
tests/cli_matrix.rsandsrc/share.rstests - completion install/candidates -> update
tests/cli_matrix.rsandsrc/completion.rstests - profile resolution logic -> update
src/profile.rstests and related CLI matrix cases
🧩 Feature Areas & Ownership Map
- CLI / UX:
src/cli.rs,src/help.rs,README.md - Persistence:
src/config/*,src/share.rs - Profiles / resolution:
src/profile.rs - Game observation / matching / bindings:
src/detect.rs,src/bindings.rs - Launch execution:
src/launch.rs,src/env.rs - Diagnostics:
src/doctor.rs,src/status.rs - Failure popup behavior:
src/main.rs,src/notify.rs - Completion UX:
src/completion.rs
⚠️ Known Issues / Tech Debt
README.mdhas a Quick Start numbering/order inconsistency and could use a cleanup pass.- Completion still includes generic clap-level suggestions like
--helpin some contexts; dynamic candidates are layered on top, not full custom shell UX. - Elvish completion install is not as automated as bash/zsh/fish/PowerShell.
- Project still has no Git repo/public release metadata/package workflow despite the roadmap discussing future distribution.
🔄 Update Triggers
Update this file when:
- a top-level command or subcommand is added/removed/renamed
- a persisted file path or format changes
- a new top-level source module is added
- a new major feature area appears
- the launch/completion/share architecture changes materially
Do not update this file for:
- tiny wording tweaks
- purely internal refactors that do not change ownership or edit paths
- dependency version bumps unless they change how the project is operated
📝 Change Log (agent session)
- [2026-03-21] Initial map created for the current
gamewrapRust CLI structure and feature set. - [2026-03-21] Reworked the map into a more tactical index centered on hot paths, persistence contracts, command surface, and update triggers.
- [2026-05-31] Added TTY/NO_COLOR-aware ANSI output helpers for doctor and status rendering.
- [2026-05-31] Added game forget, config edit, profile list/tree improvements, and notify test commands.
- [2026-05-31] Added gamescope settings, launch wrapping, dependency diagnostics, completion candidates, and docs.
- [2026-06-06] Removed retired setting aliases and added automatic and explicit TOML migration for configs and profile exports.
- [2026-05-31] Added observed-game display names, launch timestamps/counts,
last,game rename, andfps-cap. - [2026-05-31] Added per-profile env overrides, vkBasalt support, and Proton esync/fsync compatibility controls.
- [2026-05-31] Added pre-launch shell hooks plus persisted/dry-run/doctor visibility for deferred post-launch hooks.
- [2026-06-05] Expanded gamescope config surface: nested-width/height, unfocused-fps, scaler (-S), filter (-F), sharpness, fullscreen, borderless, adaptive-sync, hdr, steam, expose-wayland. Added gamescope-mangoapp for native MangoHud overlay integration (--mangoapp flag); doctor warns when mangohud prefix is used inside gamescope without mangoapp.
- [2026-06-06] Added optional vkbasalt-config profile/default setting and gated VKBASALT_CONFIG_FILE launch environment support.
- [2026-06-06] Replaced gamescope fullscreen/borderless toggles with
gamescope-modeand added native display resolution detection for output width/height. - [2026-06-06] Clarified unset values in
config showand addedconfig reset --allfor restoring built-in defaults. - [2026-06-06] Added gamewrap decision logging plus MangoHud session logging and vkBasalt log-level settings.
- [2026-06-06] Made
config showdisplay only explicitly configured defaults, with--effectivefor the full computed view. - [2026-06-06] Added --effective flag to
profile showand profile sections ofconfig show; default now shows only explicitly configured profile settings. - [2026-06-06] Renamed the MangoHud/GameMode settings to
mangohud/gamemodewith legacy aliases, and grouped settings help with per-tool filters. - [2026-06-06] Removed profile inheritance, flattened resolution to defaults plus one profile, and made config/profile exports sparse.
- [2026-06-14] Added hook-errors setting (warn/fail) to control pre-launch hook failure behavior; ensured post-hook runs after game spawn failures; propagated game exit codes; centralized hook execution via run_hook().
- [2026-06-14] Consolidated repeated config string mappings, resolved-setting application, and color helpers with local macros.