diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..392ec16 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,107 @@ +# AGENTS.md + +Guidance for AI coding agents working on this repository (the Steam Machine +live ISO: CachyOS + the Steamify installer step). See `README.md` and +`TODO.md` for what's built and what's left; this file is operational +knowledge — how to test/build/debug it without rediscovering the same +things every session. `TODO.md` should stay a plain task list; lessons and +gotchas belong here instead. + +Full build/test workflow (VM scripts, snapshots, cache setup) lives in the +`steam-machine-iso` and `cachyos-vm-testing` skills in `steamify-cachyos-dev` +— load those first. This file is the overflow: things worth knowing that +don't fit a skill's step-by-step flow. + +## Calamares modules + +- Verify a module is actually installed (`ls /usr/lib/calamares/modules`) + before writing QML/config for it. A `.conf` file existing is not proof — + CachyOS's own `cachyos-calamares-next` build explicitly skips + `packagechooserq` (`-DSKIP_MODULES=...`). +- Read a module's *actual* logged global-storage writes (Calamares debug + log, `-D6`), not its UI label text, to know what a `mode`/`method` really + does. +- `packagechooser`'s multi-select only works with Shift/Ctrl-click (a plain + click replaces the selection) and its UI has no visible checkboxes — not + usable as the Steamify page. Use `packagechooserq` (custom QML, + qtplugin/legacy) or `netinstall` (checkbox tree) instead. +- `packagechooserq` is built out of tree against the installed Calamares + CMake config (`/usr/lib/cmake/Calamares`) with + `-DWITH_QML=ON -DQT_VERSION_SUFFIX=-qt6 -Dqtname=Qt6 -DWITH_QT6=ON`; + `find_package(KF6CoreAddons)` must come before `find_package(Calamares)` + or the build fails with "KF6::CoreAddons target not found". Its `Config` + class (and `prettyStatus()`'s raw `Install option: ` text) is shared + with the plain `packagechooser` module — override `prettyStatus()` in + `PackageChooserQmlViewStep.cpp` itself (not `Config.cpp`) to change only + this module's Summary display without affecting `packagechooser@desktop` + etc. elsewhere in the installer. +- Both `packagechooserq` (QML swap) and `netinstall` (config swap) are + testable live in a booted ISO VM with no rebuild: edit + `/etc/calamares/modules/*.conf` + `settings.conf` + (`steamify-cachyos-dev/share/sq.sh` / `sn.sh`), relaunch + `pkexec-wrapper calamares -D6` in a **separate Konsole tab** (it blocks + the tab it runs in; typing into that same tab just echoes inertly into + its blocked stdin). A C++ module change needs an actual rebuild + (out-of-tree, in the build VM) and redeploying the `.so` — no shortcut. + +## ISO permissions + +`steamify-prepare.sh` fetches `steamify.sh` with `curl -o`, which doesn't +carry the executable bit, and `archiso/profiledef.sh`'s `file_permissions` +map is the only other place permissions get fixed up on the ISO — any path +not listed there stays at whatever `curl`/`cp` gave it. `calamares-online.sh` +execs `steamify.sh` directly (not via `bash`) to regenerate `Items.qml`/ +`items.json` at boot; without +x that failed *silently* (its stderr is +redirected to `/dev/null`), so the page kept working off build-time +fallbacks with no visible error. When something the ISO downloads or copies +at build time needs to run directly (not `bash script.sh`), add it to +`file_permissions` — don't assume the source already had the right mode. + +## Driving a live/installer session via QMP + +- Don't screenshot-poll for VM readiness. Pass `VM_SERIAL=` to + `run.sh`/`vmisoboot.sh` (logs `console=ttyS0` to a plain text file) and + grep that instead — near-zero tokens vs. repeated screenshot + image + analysis. Only screenshot at real decision points (to show the user, or + to check a layout), not as a polling mechanism. +- The live session's keyboard layout keeps drifting to Dutch (e.g. after + Calamares' Welcome page's keyboard preview, or after opening System + Settings), which silently breaks `qmptype.py`'s US-layout character map + (`/` → `-`, `&`/`>` fail outright) with no error for the common + substitutions. Check with a no-symbols probe (`echo test123`) after any + language/keyboard step. Typing `setxkbmap us` via QMP does fix it. +- `qmptype.py` has no key mapping for `&` or `>` at all: a typed command + using either raises "no key for" and can leave an unterminated quote in + the shell's input buffer (symptom: the prompt shows a bare `>` + continuation). Send Ctrl+C before retyping. Avoid redirection/`&&` in + typed commands entirely — write the commands to a file on the shared + `vmtools`/`share` mount and run `bash /media/foo.sh` instead, since a + file's contents aren't typed character-by-character and have no such + limits. +- Send QMP keystrokes one command at a time with a beat (~1-2s) in between. + Firing several `qmptype.py` calls back-to-back can interleave with the + guest's own prompt redraw and garble the input (seen as commands merging + or a stray leading character). +- Calamares page Next/Back buttons move vertically as page content + grows/shrinks: re-screenshot and re-locate the button after every page + change, don't reuse a fixed y-coordinate. +- A second `pkexec-wrapper calamares -D6` while an earlier failed + instance's window is still open just prints "Calamares is already + running.": close that window first (Cancel/Afbreken, then confirm the + "really cancel?" dialog). + +## Build VM SSH flakiness + +The build VM's guest sshd applies OpenSSH's `PerSourcePenalties`: repeated +quick reconnect attempts within its window make `ssh`/`scp` fail instantly +with "Connection closed" (verbose: "Not allowed at this time"), and further +quick retries seem to extend the penalty rather than reset it. Don't +retry-loop through it — that makes it worse. Either back off for a good +while (minutes, not seconds) with zero attempts in between, or just restart +the VM, which clears its in-memory penalty state immediately and is +usually faster than waiting it out. + +Large `scp` transfers (e.g. the ~3.2GB built ISO) over this same flaky link +can report "Connection closed" while actually still having copied fully — +check the destination file's size/timestamp before assuming a real +failure, and retry the copy (it's idempotent) rather than the whole build. diff --git a/TODO.md b/TODO.md index c7ab10d..49491f4 100644 --- a/TODO.md +++ b/TODO.md @@ -2,31 +2,14 @@ ## Open -1. **Steamify installer page** (2026-09-28, working end to end). - `packagechooserq` (custom QML) doesn't exist in CachyOS's own - `cachyos-calamares-next` build (`-DSKIP_MODULES=...packagechooserq...`), - so it's built out of tree against the installed Calamares headers (see - the build VM notes in the steam-machine-iso skill) and its `.so` + - `module.desc` are baked straight into `archiso/airootfs/usr/lib/calamares/ - modules/packagechooserq/` (no conflict: the package never ships that - path). `netinstall` (checkbox tree) stays as a manually-swappable - fallback (`steamify-cachyos-dev/share/sn.sh` + `nisteamify.conf`) for - when the module can't load, but isn't wired into `calamares-online.sh` - automatically yet — see the version-mismatch item below. - - **Fixed this session**: selected-row contrast (border-only highlight, - was a translucent teal fill making white text unreadable), page - background (was falling through to Calamares' white default), a - sub-option `└` marker, more right padding so the row border clears the - scrollbar, Summary step showing readable labels (packagechooserq's - `prettyStatus()` overridden, only for this module instance, to render - an HTML bullet list from a new `items.json` that `calamares-online.sh` - writes next to `Items.qml`), and a **pre-existing bug**: `steamify.sh` - on the ISO was never executable (`curl -o` in `steamify-prepare.sh` - doesn't set +x, and `profiledef.sh`'s `file_permissions` never listed - it), so `calamares-online.sh`'s direct exec of it - (`"$sbin" --defaults --list`) silently failed and `items.json` (no - static fallback) was never written — fixed by adding the path to - `file_permissions`. +1. **Steamify installer page** (2026-09-28, working end to end; see + `AGENTS.md` for the module/build/testing details and gotchas behind + this). `packagechooserq` (custom QML) is built out of tree and baked + straight into `archiso/airootfs/usr/lib/calamares/modules/packagechooserq/`. + `netinstall` (checkbox tree) stays as a manually-swappable fallback + (`steamify-cachyos-dev/share/sn.sh` + `nisteamify.conf`) for when the + module can't load, but isn't wired into `calamares-online.sh` + automatically yet. - **Still open**: - Bake the `packagechooserq` *build* into the ISO build pipeline itself (a `build-calamares-modules.sh` step: install @@ -47,44 +30,6 @@ `packagechooser_steamifypage` GS key, or netinstall's packageOperations markers) into one `steamifyChoice` GS key, so `shellprocess_steamify.conf` doesn't need to know which page ran. - - **Lessons learned**: - - Verify a Calamares module is actually installed - (`ls /usr/lib/calamares/modules`) before writing QML/config for it; - `packagechooser`'s multi-select needs Shift/Ctrl-click (plain click - replaces the selection) — not usable as-is, `packagechooserq` or - `netinstall` only. - - Both pages are testable live in the booted ISO VM with no rebuild: - hot-swap `/etc/calamares/modules/*.conf` + `settings.conf` - (`share/sq.sh` / `share/sn.sh`), relaunch - `pkexec-wrapper calamares -D6` in a **separate Konsole tab** (it - blocks the tab it runs in). A C++ module change needs a real - rebuild (out-of-tree, in the build VM) + redeploy of the `.so`, no - shortcut. - - The live session's keyboard layout keeps drifting to Dutch (e.g. - after Calamares' Welcome page, or after opening System Settings), - breaking `/`/`(`/`)`/`&`/`>` in `qmptype.py`'s US-layout map with no - error for the common ones (`/` → `-`) — `setxkbmap us` typed via - QMP *does* fix it (unlike the earlier Wayland claim), but check - with a no-symbols probe after any language/keyboard step regardless. - - `qmptype.py` has no key for `&` or `>` at all: a typed command using - either raises "no key for" and can leave an unterminated quote in - the shell's input buffer; send Ctrl+C before retyping. Avoid - redirection/`&&` in typed commands — write it to a file and run - `bash /media/foo.sh` instead, since a file's contents aren't typed - character-by-character. - - Send QMP keystrokes one command at a time with a beat in between; - firing several `qmptype.py` calls back-to-back can interleave with - the guest's own prompt redraw and garble the input. - - Don't screenshot-poll for VM readiness: pass `VM_SERIAL=` to - `run.sh`/`vmisoboot.sh` and grep the plain-text serial log instead - (near-zero tokens vs. repeated screenshot+image-analysis). - - The build VM's guest sshd applies OpenSSH's `PerSourcePenalties`: - repeated quick reconnect attempts within its window make `ssh`/`scp` - fail instantly with "Connection closed" (verbose: "Not allowed at - this time"), and each further attempt seems to extend the penalty - rather than reset it. Don't retry-loop through it; back off for a - while, or just restart the VM (clears its in-memory penalty state - immediately) instead of waiting it out. 2. **Check the live name** (the build tree has it right: `build/x86_64/airootfs/etc/os-release`) after the next build: Hello's subtitle should say