Commit Graph
383 Commits
Author SHA1 Message Date
Outis b4d408593d Merge pull request #119 from outis1one/claude/zealous-heisenberg-8ylloi
fix: search all Wolf Steam homes for AppID prefix, not just head -1
2026-06-22 16:41:49 -04:00
Claude dd56f3f837 fix: search all Wolf Steam homes for AppID prefix, not just head -1
With multiple WolfSteam containers running, _steam_home() picks the first
Steam directory found which may not contain the target game's prefix.
_apply_ea_fix now scans all Wolf Steam homes and selects the one that has
the AppID's Proton prefix, falling back to the original behavior if none
match.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 20:40:39 +00:00
Outis bd4f3ee40d Merge pull request #118 from outis1one/claude/zealous-heisenberg-8ylloi
fix: lock config directory so Steam cannot overwrite launch options
2026-06-22 14:12:18 -04:00
Claude 77e40d4955 fix: lock config directory so Steam cannot overwrite launch options
Steam writes localconfig.vdf via atomic rename (write temp + rename over
original). chmod 444 on the file is bypassed by the rename. chmod 555 on
the directory blocks rename-into, preserving the launch option across
Steam restarts.

Also unlocks the directory at the start of step 6 so re-running the
script can update the launch option.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 18:08:57 +00:00
Outis 0f8615e0ec Merge pull request #117 from outis1one/claude/zealous-heisenberg-8ylloi
fix: detect existing EA Desktop install, skip MSI extraction if Link2…
2026-06-22 13:53:56 -04:00
Claude 0c56837505 fix: detect existing EA Desktop install, skip MSI extraction if Link2EA.exe present
On native Linux Steam, EA App self-installs via EAappInstaller.exe on first
SWBF2 launch. Link2EA.exe appears in the Wine prefix without any MSI extraction.
Script now checks for Link2EA.exe first and skips steps 2-3 (MSI locate +
extract) if EA Desktop is already installed, proceeding directly to writing
registry fix files and the launch wrapper.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 17:51:58 +00:00
Outis c90f867e27 Merge pull request #116 from outis1one/claude/zealous-heisenberg-8ylloi
fix: search game files for ea_app.msi, not just drive_c
2026-06-22 13:29:56 -04:00
Claude e33b2f6491 fix: search game files for ea_app.msi, not just drive_c
The MSI is bundled in steamapps/common with the game files. The script
was only checking drive_c (where Steam copies it after a launch), causing
a false "not found" error before the user had launched the game.

Now searches steamapps/common and all of steamapps as fallbacks, reports
which path it found the MSI at. Also remove stale references to the
"Origin is not installed" error which no longer appears.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 17:23:43 +00:00
Outis 1e725e15b1 Merge pull request #115 from outis1one/claude/zealous-heisenberg-8ylloi
feat: auto-install msitools in both SWBF2 setup scripts
2026-06-22 13:02:09 -04:00
Claude 92fd67ec34 feat: auto-install msitools in both SWBF2 setup scripts
Both scripts now detect and install msitools if missing, supporting
apt-get (Debian/Ubuntu), dnf (Fedora), and pacman (Arch). Falls back
to a clear error if the package manager is not recognised.

Remove msitools from manual prerequisites in the doc.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 16:31:42 +00:00
Outis 36413a1c96 Merge pull request #114 from outis1one/claude/zealous-heisenberg-8ylloi
feat: add GE-Proton auto-install to both SWBF2 setup scripts
2026-06-22 12:29:32 -04:00
Claude 7f926c03af feat: add GE-Proton auto-install to both SWBF2 setup scripts
Both scripts now download and install GE-Proton10-34 if not already present:
- setup-swbf2-linux.sh: installs to ~/.steam/root/compatibilitytools.d/
- setup-swbf2-wolf.sh: installs into the WolfSteam container via docker cp + tar

Both pause after install and prompt the user to set GE-Proton in Steam
(Compatibility → Force) before continuing, since that step requires the GUI.

Update docs to reflect GE-Proton is now handled automatically.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 16:15:24 +00:00
Outis ae8c73ff74 Merge pull request #113 from outis1one/claude/zealous-heisenberg-8ylloi
docs: rename wolf-setup to linux-setup, native Linux section first
2026-06-22 12:12:54 -04:00
Claude 1b29873f62 docs: rename wolf-setup to linux-setup, native Linux section first
- Rename SWBF2-2017-wolf-setup.md -> SWBF2-2017-linux-setup.md
- Move Native Linux Steam section before Wolf/Moonlight section
- Update TOC link order to match

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 14:37:46 +00:00
Outis 26f8de7a72 Merge pull request #112 from outis1one/claude/zealous-heisenberg-8ylloi
docs: rewrite SWBF2 setup guide as clean how-to with native Linux sec…
2026-06-22 10:31:09 -04:00
Claude 11a7c6529c docs: rewrite SWBF2 setup guide as clean how-to with native Linux section
- Remove editorial content (EA server speculation, 2005 alternative, opinions)
- Add native Linux Steam section covering all six setup steps
- Add separate key paths tables for Wolf and native
- Add native Linux troubleshooting commands alongside Wolf equivalents
- Rename title to reflect both platforms
- Fresh install table rewritten as factual survival matrix

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 14:21:22 +00:00
Outis 1f10403f5d Merge pull request #111 from outis1one/claude/zealous-heisenberg-8ylloi
docs: add SWBF2 2017 discovery writeup explaining why the fix works
2026-06-22 10:07:06 -04:00
Claude 4324ad7ce2 docs: add SWBF2 2017 discovery writeup explaining why the fix works
Long-form document tracing the actual discovery process: the wrong turns,
the aha moments, and the reasoning behind each step. Covers:

- Why EA is involved in a Steam game at all (link2ea:// architecture)
- JunoConfigureRegistry failure and why DISABLEROLLBACK was a dead end
- msiextract bypass as the actual solution
- Why direct system.reg edits don't survive reboots (wineserver ownership)
- The launch wrapper approach for registry persistence
- RPC_S_SERVER_UNAVAILABLE and EALocalHostSvc
- Wolf-specific bwrap capabilities mismatch
- localconfig.vdf atomic rename problem and chmod 555 fix

Written for sharing — no identifying information, explains the "why"
for each fix so readers can adapt if EA changes their MSI structure.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 13:26:11 +00:00
Outis 7affc4c50e Merge pull request #110 from outis1one/claude/zealous-heisenberg-8ylloi
feat: add standalone SWBF2 2017 setup scripts for Wolf and native Lin…
2026-06-22 09:05:56 -04:00
Claude c6d58a7ccd feat: add standalone SWBF2 2017 setup scripts for Wolf and native Linux Steam
Two self-contained scripts for getting SWBF2 (2017, AppID 1237950) working
with GE-Proton on Linux — no dependency on the ubuntu-post-install framework.

setup-swbf2-wolf.sh  — for Wolf/Games-on-Whales + Moonlight streaming
setup-swbf2-linux.sh — for native Linux Steam (no Docker)

Both implement the same core fix:
- msiextract bypass for JunoConfigureRegistry Wine incompatibility
- EA Desktop files copied into Wine prefix from extracted MSI
- link2ea_fix.reg + ea_services.reg written to drive_c
- Launch wrapper that imports .reg files via Proton on every launch
  (direct system.reg edits are overwritten by wineserver on shutdown)

Wolf version also handles Docker cp, container paths, STEAM_UNIX_SOCKET,
and localconfig.vdf directory locking inside the Wolf state folder.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 12:59:49 +00:00
Outis 94fe961b72 Merge pull request #109 from outis1one/claude/zealous-heisenberg-8ylloi
Claude/zealous heisenberg 8ylloi
2026-06-22 08:48:43 -04:00
Claude 8084276738 feat(wolf): add setup-swbf2 command for full SWBF2 2017 Wolf/Moonlight setup
Automates the complete working solution for SWBF2 (AppID 1237950) on Wolf:

1. Extracts EA Desktop from ea_app.msi using msiextract on the host,
   bypassing JunoConfigureRegistry Wine incompatibility that causes MSI rollback
2. Copies EA Desktop files (Link2EA.exe, EALocalHostSvc.exe, etc.) into the
   Wine prefix at the versioned path with symlink
3. Writes link2ea_fix.reg and ea_services.reg into drive_c so they persist
   across Wine prefix operations
4. Installs a launch wrapper (/home/retro/ea_install.sh) that runs regedit
   via Steam's sniper+GE-Proton launch chain — required because direct edits
   to system.reg are overwritten when wineserver flushes on shutdown
5. Sets LaunchOptions for AppID 1237950 in localconfig.vdf and locks the
   config directory (chmod 555) to prevent Steam overwriting it via
   atomic rename on shutdown

Run after: Steam open in Moonlight, GE-Proton set, SWBF2 launched once
(triggers Wine prefix + ea_app.msi creation), EA account linked at ea.com.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 12:38:05 +00:00
Claude b756e7eedb docs: rewrite SWBF2-2017 guide with working msiextract + wrapper solution
Complete rewrite reflecting the actual working setup:
- msiextract on host bypasses JunoConfigureRegistry Wine incompatibility
- Wrapper script imports registry fixes via regedit through Steam's launch chain
- chmod 555 on config dir prevents Steam overwriting localconfig.vdf
- Honest fresh-install assessment table (what's automated vs one-time manual)
- Troubleshooting section covering all errors encountered
- Key paths reference table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 12:35:14 +00:00
Claude 5cff764d3b docs: add EA auth dependency context, login process, and longevity notes
Documents the EA account requirement, first-time login flow, credential
caching for machine transfers, community server options if EA shuts down,
and the SWBF2 2005 alternative for a launcher-free experience.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 05:02:19 +00:00
Claude 6b385e62ba docs: update SWBF2 guide with direct-exe bypass and Origin registry spoof
Revised approach: skip link2ea:// and EA App account requirement entirely.
Launch starwarsbattlefrontii.exe directly via the wrapper, spoof Origin
registry entries so the game's built-in launcher check passes. Documents
what doesn't work and why (msiexec/bwrap/EA account issues).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 04:25:26 +00:00
Outis 8114572eea Merge pull request #108 from outis1one/claude/zealous-heisenberg-8ylloi
docs: add SWBF2 2017 Wolf/Moonlight setup guide
2026-06-21 23:59:57 -04:00
Claude 0202515163 docs: add SWBF2 2017 Wolf/Moonlight setup guide
Documents the EA App installation workaround for Star Wars Battlefront II
(2017) running under Wolf/WolfSteam with GE-Proton10-34. Covers the bwrap
capability problem, Steam launch wrapper trick, msiextract bypass for the
JunoConfigureRegistry Wine incompatibility, and correct EA Desktop file layout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-22 03:56:56 +00:00
Outis afa6145784 Merge pull request #107 from outis1one/claude/zealous-heisenberg-8ylloi
fix(wolf): use wineserver -f as anchor instead of cmd.exe timeout
2026-06-21 15:22:22 -04:00
Claude b031d7e7d4 fix(wolf): use wineserver -f as anchor instead of cmd.exe timeout
wine cmd.exe /c "timeout /t 900 > nul" failed silently (docker exec -d
hides errors), leaving no anchor process and letting wineserver die as
soon as EAappInstaller.exe exited.

Replace with wineserver -f (foreground mode) which keeps the server
alive unconditionally until explicitly killed with wineserver -k.
This is the correct primitive for holding a Wine session open.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-21 19:21:40 +00:00
Outis 7802e7eb70 Merge pull request #106 from outis1one/claude/zealous-heisenberg-8ylloi
fix(wolf): keep wineserver alive during EA App install
2026-06-21 15:15:29 -04:00
Claude 70a7b83cc4 fix(wolf): keep wineserver alive during EA App install
EAappInstaller.exe is a WiX/Burn bootstrapper that spawns the real
installer as a background Wine process and exits immediately. When the
foreground wine process exited, wineserver shut down and killed the
background installer before it could write any files.

Fix: launch a cmd.exe/timeout anchor before running the installer so
the shared wineserver stays up while background installer processes run.
Kill the anchor (wineserver -k) after EADesktop.exe is detected or the
15-minute timeout expires.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-21 19:13:59 +00:00
Outis 5c0cad20b1 Merge pull request #105 from outis1one/claude/zealous-heisenberg-8ylloi
wolf: fix install-ea-app — correct installer path, clear fake Install…
2026-06-21 15:03:16 -04:00
Claude 7eadf642b7 wolf: fix install-ea-app — correct installer path, clear fake InstallSuccessful
Two bugs in install-ea-app:

1. Installer search included compatdata (the Wine prefix), so it found the
   temp-extracted copy at drive_c/windows/temp/{UUID}/.cr/EAappInstaller.exe
   instead of the bundled copy at steamapps/common/…/__Installer/…/
   Fixed: search only under steamapps/common.

2. Our fake InstallSuccessful=true (written by fix-ea-game to bypass the
   install-script loop) caused EAappInstaller to detect EA App as "already
   installed" and exit in ~15 seconds without doing anything.
   Fixed: delete the InstallSuccessful values via wine reg delete inside the
   container BEFORE launching the installer. The real EA App installer writes
   them back correctly after a successful install.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-21 19:02:04 +00:00
Outis bebce48aff Merge pull request #104 from outis1one/claude/zealous-heisenberg-8ylloi
Claude/zealous heisenberg 8ylloi
2026-06-21 14:55:41 -04:00
Claude ddf481b72f wolf: add install-ea-app and diagnose-ea, fix link2ea registration
install-ea-app: runs EAappInstaller.exe inside the WolfSteam container
using GE-Proton's wine binary. The container has a virtual display so the
EA App installer GUI appears in Moonlight; the user clicks through it and
logs in to their EA account. After EA App installs, fix-ea-game registers
the link2ea:// handler and clears the install-script loop.

diagnose-ea: prints the current link2ea:// registry state from both
system.reg and user.reg, locates EADesktop.exe/Link2EA.exe, shows
StateFlags, and tails the relevant Proton log lines — the first thing to
run when the game returns straight to the Play screen.

_apply_ea_fix: now checks user.reg as well as system.reg for an existing
link2ea:// registration (GE-Proton writes to user.reg during prefix setup);
also searches for Link2EA.exe as a fallback handler when EADesktop.exe is
not yet installed; reports a clear next step when neither is found.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-21 18:50:22 +00:00
Claude 02ae1ae02c wolf: pre-download GE-Proton at install time, auto-extract on start
GE-Proton is required for EA games but was a manual step users had to
remember after first Steam launch. This change eliminates that gap:

- install_wolf() downloads the GE-Proton tarball to
  ~/docker/wolf/ge-proton-cache/ during initial setup (~500 MB, runs
  before the "Start Wolf now?" prompt so it's ready immediately)
- _cache_ge_proton() helper in manage.sh does the same on demand
- ge-proton subcommand checks the cache dir first and extracts from
  there instead of re-downloading (~instant vs ~500 MB download)
- start subcommand auto-extracts the cached tarball into Steam's
  compatibilitytools.d if Steam has already launched at least once,
  so GE-Proton appears in the Compatibility dropdown without any
  manual ./manage.sh ge-proton step

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-21 17:27:19 +00:00
Outis c5e542d7ea Merge pull request #103 from outis1one/claude/zealous-heisenberg-8ylloi
wolf: register link2ea:// handler and add wait-ea-app subcommand
2026-06-21 12:51:15 -04:00
Claude ef6a63a908 wolf: register link2ea:// handler and add wait-ea-app subcommand
SWBF2 (AppID 1237950) launches, calls ShellExecute("link2ea://..."),
and exits. Without a link2ea:// URL protocol handler registered in the
Wine registry, ShellExecute returns error 31 and the game never plays.

_apply_ea_fix now also writes the link2ea:// Classes registry keys
pointing to EADesktop.exe when it is found in the Proton prefix. If
EADesktop.exe is not yet present (EAappInstaller runs async via
RunType=1 in installScript.vdf), the function warns and skips the
handler registration with instructions to run wait-ea-app.

New 'wait-ea-app [appid]' subcommand polls every 15 seconds (up to 20
minutes) for EADesktop.exe to appear, then calls _apply_ea_fix so the
full fix including the link2ea:// handler is applied automatically once
EA App finishes installing in the background.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-21 16:50:03 +00:00
Outis 6cd9f9772a Merge pull request #102 from outis1one/claude/zealous-heisenberg-8ylloi
Claude/zealous heisenberg 8ylloi
2026-06-21 01:13:59 -04:00
Claude a1b4107e3e fix(wolf): stop Steam container before patching EA registry to survive wineserver flush
wineserver holds the Wine registry in memory and flushes it back to
system.reg on shutdown, overwriting any edits made while the container
is running. _apply_ea_fix now stops the WolfSteam container first,
patches system.reg + appmanifest StateFlags on disk, then restarts Wolf
so the keys persist when wineserver next starts.

Also sets StateFlags to 6 (fully installed) so Steam skips the
install-script phase entirely and launches the game directly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-21 05:11:40 +00:00
Claude 74d4e0d0e7 wolf: register tab-completion for both 'manage.sh' and './manage.sh'
Bash treats these as different command names so both need registering.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-21 02:24:51 +00:00
Outis 91953c233f Merge pull request #101 from outis1one/claude/zealous-heisenberg-8ylloi
Claude/zealous heisenberg 8ylloi
2026-06-20 22:10:35 -04:00
Claude f462c6baa2 wolf: fix steam-cache mount missing from configure-apps CATALOG block
The first Python CATALOG (used at initial install time) was missing the
steam-cache mount that the update-apps block had. Both paths now include
the persistent cache mount.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-21 02:09:52 +00:00
Claude 0785d30199 wolf: add install-completion to README manage section + tab-completion note
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-21 02:08:17 +00:00
Outis 43ad8f763a Merge pull request #100 from outis1one/claude/zealous-heisenberg-8ylloi
wolf: persist Steam shader cache across sessions
2026-06-20 21:51:59 -04:00
Claude 40bb80bc7a wolf: persist Steam shader cache across sessions
Mount GAME_STORAGE_DIR/steam-cache → /home/retro/.cache so DXVK/Mesa
Vulkan shader compilations survive container restarts. Without this the
cache lived in the ephemeral session home and was wiped on every Wolf
restart, forcing a full recompile each session.

Also create steam-cache/ in initial setup and update-storage so the
directory exists with correct uid-1000 ownership before the container
first starts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-21 01:50:25 +00:00
Outis 70abc9430b Merge pull request #99 from outis1one/claude/zealous-heisenberg-8ylloi
wolf: make 'games' interactive — pick a number to apply the EA fix
2026-06-20 20:41:00 -04:00
Claude 3f6e359c7b wolf: make 'games' interactive — pick a number to apply the EA fix
./manage.sh games now lists installed games numbered with their AppIDs,
then prompts for a number to apply the EA App install-script fix to that
game (Enter to skip). Factored the reg-fix into a shared _apply_ea_fix
helper used by both 'games' and 'fix-ea-game'. The EA Desktop installed
marker is shared across all EA titles, so the same fix works for any EA
game — the picker just supplies the right per-game AppID.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-21 00:02:48 +00:00
Outis bbaa0e63df Merge pull request #98 from outis1one/claude/zealous-heisenberg-8ylloi
Claude/zealous heisenberg 8ylloi
2026-06-20 19:55:34 -04:00
Claude d32832ec75 wolf: add tab-completion + clarify fix-ea-game is universal for EA titles
- install-completion: writes a bash completion script to
  ~/.bash_completion.d/manage-wolf and registers it, so double-tab
  after './manage.sh ' shows all available commands.
- fix-ea-game kept as general name (not fix-swbf2-2017): the EA Desktop
  registry key is shared across all EA games; the Valve has-run key
  follows the same EADesktopSetup pattern across EA's catalog.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01D8ckUJQtj1pH8jtAddBDZs
2026-06-20 23:53:00 +00:00