Files
steamify-cachyos/AGENTS.md
T
theupriser d654d44b6a fix: Single-file build for curl, published by GitHub Actions
tools/bundle.sh inlines lib/ into one script; the workflow builds and
checks it on every push and PR, and on main publishes it to the rolling
"latest" release. Piped in via curl, it reattaches the terminal so the
menu keeps working.
2026-09-23 15:37:06 +02:00

123 lines
6.5 KiB
Markdown

# AGENTS.md
Guidance for AI coding agents working on this repository. See `README.md`
for what the script does from a user's point of view.
## Project overview
A bash wizard that makes CachyOS (KDE Plasma 6 + `plasma-login-manager`)
boot into a SteamOS-style gamescope session, with working switching between
gamescope and the Plasma desktop. Primary target: the Valve Steam Machine
(DMI `Valve`/`Fremont`) running CachyOS Desktop edition.
## Layout
- `setup-gamescope-boot.sh` - the only entry point. Pre-flight checks,
sources `lib/*.sh`, runs the menu and applies the plan. No component
logic here.
- `lib/*.sh` - one file per responsibility, each defining functions only
(no top-level side effects besides constants). See the table in
`README.md`.
- **Components.** Every menu item `<id>` (listed in `COMPONENTS` and `LABEL`
in `lib/menu.sh`) provides `<id>_status` (return 0 if on, detected from
the system, no state file needed), `<id>_enable` and `<id>_disable`, all
idempotent. `<id>_enable` is also used to re-apply. Optional
`<id>_available` is checked via `component_available` (e.g. `machine`
only on Fremont). Turn-on order is `COMPONENTS` order, turn-off reverse;
`gaming` must stay first. Dependencies live in `toggle_component`.
- **Reversibility.** Every per-user KDE setting a component changes goes
through `kset <component> <file> <group|group> <key> <value>`
(`lib/state.sh`), which records the old value once; `<id>_disable` calls
`krevert <component>`. Never call `kwriteconfig6` directly for settings a
component owns. System files are backed up with `backup_file` and restored
on disable.
- **Single-file build.** `tools/bundle.sh` inlines `lib/*.sh` in the order of
the entry point's `for lib in ...; do` source loop and wraps everything
after that loop in `main()`. Keep that loop on one line, keep all logic in
functions, and don't rely on `SCRIPT_DIR` for anything but sourcing.
CI (`.github/workflows/bundle.yml`) publishes the bundle to the `latest`
release on pushes to `main`.
## Conventions
- Bash, `set -uo pipefail` (no `-e`): check exit codes of steps that matter
explicitly (`|| { err ...; exit 1; }` or `|| return 1`).
- Use the helpers from `lib/common.sh` (`info`, `ok`, `warn`, `err`,
`ask_yn`, `backup_file`) for all output and prompts.
- Runs as the normal user; use `sudo` per command, never require root.
Per-user files go in `$HOME` of the invoking user (the script refuses to
configure another user).
- **Idempotent**: every step must be safe to re-run without duplicating
lines or settings. Back up system files with `backup_file` before the
first edit.
- Don't overwrite package-owned files in `/etc/xdg` or `/usr`. KDE settings
go into the user's config via `kwriteconfig6` (or `merge_kde_config` for
whole Valve ini files).
- Package installs after a user already confirmed use `--noconfirm`: a
second pacman prompt consumes the next scripted answer.
- Comments explain *why* (the CachyOS/Plasma quirk being worked around),
not what the next line does.
## Non-obvious behaviour to preserve
- `apply_changes` sets `$LOGIN_MANAGER` from the menu: `sddm` when single
user mode is wanted, else `plasmalogin`. Toggling single user re-applies
`gaming` so it moves to the other login manager. Single user mode hides
the launcher's Session dropdown via kickoff `primaryActions=3` (restricting
`action/logout` also hides Restart/Shut Down). Two login-manager paths:
**sddm** (like SteamOS: `steam-set-session` writes
`/etc/sddm.conf.d/zz-steamos-autologin.conf`, which SDDM honours; we add
`User=`/`Relogin=` in `10-gamescope-autologin.conf`, and `/etc/sddm.conf`
must not contain `[Autologin]` since it's read last) and **plasmalogin**
(needs the sync bridge and the shortcut's sudoers rule). Both must keep
working.
- `steam-set-session` only writes `/etc/plasmalogin.conf.d/zz-steamos-autologin.conf`;
the base `/etc/plasmalogin.conf` wins, hence the sync bridge. The sync
service needs `StartLimitIntervalSec=0`, or bursts of session switches
get it rate-limited and all later switches silently stop working.
- The sync script must only edit `Session=` inside `[Autologin]`.
- The Steam desktop autostart unit is guarded with
`ExecCondition=... XDG_CURRENT_DESKTOP = KDE`, so it doesn't start a
second Steam inside gamescope.
- Vapor theme: install Valve's files as shipped. Don't rewrite Valve's
`metadata.json`; the icon theme is `breeze-dark` (there is no "Vapor"
icon theme); wallpapers are flat JPGs in `usr/share/wallpapers`.
`lookandfeeltool` does not switch the color scheme, so
`plasma-apply-colorscheme Vapor` is applied explicitly.
- Plasma 6 has no separate systemtray containment: tray settings live on
the systemtray applet itself (Valve's setup script targets Plasma 5).
- Restart plasmashell via `systemctl --user` (`plasma-plasmashell.service`),
not `plasmashell --replace` from the script's shell: a shell without the
session environment yields a light-themed desktop (context menus, apps it
launches).
- Live Plasma changes (`qdbus6 ... evaluateScript`, `lookandfeeltool`) only
run when `plasmashell` is running; config-file fallbacks cover the rest.
- plasmashell writes its in-memory config back on exit: edit panel/applet/
wallpaper files only between `stop_plasmashell_for_edit` and
`restart_plasmashell_if_stopped` (`lib/common.sh`).
- LED driver: `leds-valve-dkms-git`'s Makefile builds against `uname -r`,
so the script builds explicitly for the running kernel and installs
headers for every installed kernel first. The module creates
`/sys/class/leds/valve-leds*`.
- `Relogin=true` means a gamescope that fails to start is relaunched in a
tight loop; keep that in mind when changing session handling.
## Checking changes
There is no test suite. At minimum:
```bash
for f in setup-gamescope-boot.sh lib/*.sh; do bash -n "$f"; done
shellcheck -S warning setup-gamescope-boot.sh lib/*.sh # if available
```
Behaviour is verified in a CachyOS QEMU/KVM test VM. The VM scripts and a
Claude Code skill describing the whole test workflow (snapshots, SSH, running
the wizard with scripted menu input such as `printf '2\n\ny\nn\n'`, the
per-component checks; when stdin is not a terminal the menu falls back to a
numbered prompt, which is what scripted runs use, reboot checks, the full test matrix, `--fremont` to
fake Steam Machine hardware) live in
[cachyos-gamescope-boot-dev-env](https://github.com/theupriser/cachyos-gamescope-boot-dev-env).
Gamescope itself and the real LED bar can only be verified on hardware.