Commit Graph
1235 Commits
Author SHA1 Message Date
Outis 5edfed7735 Merge pull request #424 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
Fix TI-99/4A "emulator not found" by using a real es_find_rules.xml e…
2026-09-02 15:58:20 -04:00
Claude 910a49f12f Fix TI-99/4A "emulator not found" by using a real es_find_rules.xml entry
ES-DE's findEmulator() decides found-vs-not-found from the <command>
string's emulator token, and every real %INJECT%=...esprefix example in
ES-DE's own shipped es_systems.xml (Dolphin/PrimeHack/Triforce/Supermodel)
pairs it with an %EMULATOR_X%/%CORE_X% placeholder, never a literal path.
The previous ti994a <command> used a literal "/bin/bash -c ..." after
%INJECT%=%BASENAME%.esprefix, which ES-DE reported as "emulator not found"
even though /bin/bash obviously exists on the container.

Fix: give ti99sim-sdl a real custom_systems/es_find_rules.xml entry
(TI99SIM, staticpath ~/Applications/ti99sim-sdl) and reference it via
%EMULATOR_TI99SIM%, matching the pattern every built-in standalone
emulator uses. %STARTDIR%=%EMUDIR% replaces the old shell "cd && ..."
prefix to keep ti99sim-sdl's working directory at its own install dir,
where it looks up the console ROM via a plain relative path.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6
2026-09-02 19:55:21 +00:00
Outis 22990b6583 Merge pull request #423 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
wolf: fix TI-99/4A ES-DE command line never actually updating on re-run
2026-09-02 15:38:02 -04:00
Claude b4ac5a4de0 wolf: fix TI-99/4A ES-DE command line never actually updating on re-run
Confirmed live: the command-line fix from an earlier commit (cd into
emulators/ before launching ti99sim-sdl) never reached the user's actual
es_systems.xml, because the write step's guard was "skip entirely if a
ti994a entry already exists" — which it did, with the old pre-fix
command line still in it. The check only asked whether an entry existed,
never whether its content matched the current template.

Now always strips any existing ti994a <system> block and re-adds the
current one fresh on every run, via a small python3 rewrite (regex block
removal + re-append) instead of a blind append-once guard. Tested against
a stand-in file matching the real stale content, and for idempotency
(second run doesn't duplicate the block), before pushing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6
2026-09-02 19:28:28 +00:00
Outis daf0ed11e4 Merge pull request #422 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
Claude/wolf pair port conflict 7nz8qg
2026-09-02 15:17:36 -04:00
Claude 0fe0c74235 wolf: fix Dolphin Sys folder writing to the wrong directory
Confirmed live: RetroArch's system_directory on this Wolf setup is
"~/bioses" (GoW's own shipped default, confirmed by reading a real
retroarch.cfg directly — wolf.sh never sets this itself), not RetroArch's
usual default of ~/.config/retroarch/system. The Dolphin Sys-folder
automation added earlier this session assumed the usual default and wrote
to retroarch/system/dolphin-emu/Sys on the host — a path RetroArch's own
config never actually reads, so it would have sat there doing nothing.

Now reads the real configured system_directory value out of
retroarch.cfg instead of assuming, and self-heals by moving a Sys folder
that's already sitting in the old wrong location (from before this fix)
into the correct one. Also corrects the same wrong assumption in the
MAME samples-directory documentation, which pointed at the same
retroarch/system/ default.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6
2026-09-02 19:16:05 +00:00
Claude 2e7e073b63 wolf: fix TI-99/4A console ROM location + add it via a tab-completing prompt
The build succeeded, but the follow-up message pointed at "ti99sim-sdl's
own README" for where the console ROM goes — useless, since that source
tree lived inside the throwaway build container and was already gone by
the time anyone could read it.

Got the real answer from RetroPie's own configure_ti99sim(): it symlinks
the console ROM into the emulator's own install directory, then cd's
there before launching (pushd "$md_inst" && ./ti99sim-sdl "$@") — so
ti99sim-sdl finds it via a plain relative lookup, not any search path.
Caught a real bug this exposed: our own ES-DE <command> line launched
ti99sim-sdl by full path with no cd, so even a correctly-placed file
would never have been found. Fixed to cd into emulators/ first, matching
RetroPie's own pattern exactly.

Also, instead of just printing the required path (emulators/TI-994A.ctg)
and leaving it at that, now prompts for it directly with a tab-completing
path picker (read -e -i, defaulting into the game storage dir) — if you
already have the file somewhere, it copies it into place immediately
instead of making you do it by hand afterward.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6
2026-09-02 19:11:13 +00:00
Outis f27fdad711 Merge pull request #421 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
Claude/wolf pair port conflict 7nz8qg
2026-09-02 14:58:43 -04:00
Claude e965c2bd76 wolf: build ti99sim-sdl from the real SDL2-native upstream, not a stale fork
You were right to push back on this earlier — the original ask was SDL2,
same as RetroPie, and I substituted a different thing (SDL1-compat) without
checking what RetroPie actually does first.

Checked RetroPie's own ti99sim.sh scriptmodule directly: it doesn't build
from billzajac/ti99sim (the GitHub fork the last two attempts used) at
all. It fetches upstream v0.16.0 straight from the original author's own
site (mrousseau.org), applies exactly one trivial patch (a missing
#include <cstring> for modern g++), and builds against libsdl2-dev +
libssl-dev directly — no SDL1 compatibility layer, because that source
genuinely supports SDL2 natively. The GitHub fork used previously was
just a stale, pre-SDL2-port copy under a different account.

Verified the download URL actually serves the real tarball (fetched real
binary content, confirmed the 7zXZ header) and the patch's exact content
before using either — same real-source-first standard as the wolf.sh
fixes earlier this session. Tested the sed insertion that replaces
applying the .diff against a stand-in file matching the patch's real
context before trusting it.

Also documents the exact BIOS-equivalent filename RetroPie's own docs
give for this emulator: TI-994A.ctg (case-sensitive) — a real, useful
detail that was missing before.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6
2026-09-02 18:47:07 +00:00
Claude c7cc7176f0 wolf: fix ti99sim-sdl build — it needs real SDL 1.2, not SDL2
Confirmed live: the previous sdl-config shim got past the tooling
problem, but hit a much deeper one — ti99sim's SDL frontend
(src/sdl/main.cpp) is written against the actual SDL 1.2 API and uses
symbols SDL2 genuinely removed (SDL_keysym, SDL_WM_SetCaption,
SDL_EnableUNICODE, SDL_JoystickOpened, the old integer-index
SDL_JoystickName). No shim can paper over missing symbols — this needed
the real thing.

Swapped libsdl2-dev + the hand-rolled sdl-config shim for
libsdl1.2-compat-dev — the SDL project's own official compatibility
package (libsdl-org/sdl12-compat, packaged in Ubuntu's universe repo):
genuine SDL 1.2 headers and its own real sdl-config, implemented on top
of actual SDL2 underneath. The code compiles against the API it was
actually written for, while still running on modern SDL2 at runtime.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6
2026-09-02 18:40:55 +00:00
Outis ad5440a58b Merge pull request #420 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
wolf: fix ti99sim-sdl build failing on missing sdl-config
2026-09-02 14:36:20 -04:00
Claude a55f6c430a wolf: fix ti99sim-sdl build failing on missing sdl-config
Confirmed live: the containerized ti99sim-sdl build (previous commit)
failed with "SDL.h: No such file or directory" — not a real
compatibility problem, ti99sim's own Makefile.linux calls the old SDL 1.x
sdl-config tool, which doesn't exist in modern libsdl2-dev packaging at
all (only pkg-config .pc files). Every sdl-config invocation was silently
returning nothing, so the compile got no -I/-L flags whatsoever.

Adds a small shim mapping the handful of flags this build actually uses
(--cflags/--libs/--version, tested standalone against a fake pkg-config
before pushing) onto `pkg-config sdl2`, rather than patching the
project's own Makefiles.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6
2026-09-02 18:32:35 +00:00
Outis 3b0689dfd9 Merge pull request #419 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
wolf: actually build ti99sim-sdl instead of punting it to a manual step
2026-09-02 14:28:41 -04:00
Claude 83d62b05fd wolf: actually build ti99sim-sdl instead of punting it to a manual step
Fixes a cop-out from the previous commit — rather than just warning about
a possible glibc/SDL2 mismatch and handing the user a manual build guide,
build ti99sim-sdl inside a throwaway container running the exact same
image ES-DE itself runs (ghcr.io/games-on-whales/es-de:edge), which
actually eliminates the mismatch risk instead of just noting it. Runs
during install_wolf() when the TI-99/4A prompt is accepted, skips itself
if the binary's already present, and drops the result straight into
emulators/ti99sim-sdl ready to use.

Caught a real bug before pushing, not after: `make` alone leaves the
binary under ti99sim's own src/ directory, not the repo root (confirmed
against its README), so a naive `cp ti99sim-sdl` would have failed
outright. Uses `make install` instead — the project's own reliable way to
collect the binary (copies to /opt/ti99sim/bin, symlinks into
/usr/local/bin) — rather than guessing the exact build subpath.

The one piece that's still genuinely a manual step, and stays that way:
supplying your own TI-99/4A console ROM + GROM dump, real copyrighted
console firmware no installer can legally source for you.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6
2026-09-02 18:22:40 +00:00
Outis 423b295acf Merge pull request #418 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
wolf: add Cemu (Wii U), TI-99/4A custom ES-DE system, BIOS/MAME-sampl…
2026-09-02 14:16:59 -04:00
Claude 25dc4251de wolf: add Cemu (Wii U), TI-99/4A custom ES-DE system, BIOS/MAME-samples docs
Cemu: no libretro core exists (a third-party attempt was never merged and
there are no plans to per RetroArch's own issue tracker) — added as a
fourth standalone AppImage download, same pattern as Azahar/PCSX2/Dolphin.
Its official release asset is already named Cemu-<version>-x86_64.AppImage,
matching ES-DE's own find-rule directly, so no Dolphin-style rename/symlink
is needed. Flags a real supply-chain compromise of Cemu's own Linux release
assets around v2.6 (2026-05, since restored, per Datadog Security Labs)
and that most retail games need a user-supplied Wii U common key.

TI-99/4A: added as a genuine ES-DE system (not this repo's existing
js99er service, which is browser-based and can't be launched as an ES-DE
system) via a custom_systems/es_systems.xml, per ES-DE's own documented
mechanism for extending its built-in system list. Needed a new mount
(esde-custom-systems -> ~/ES-DE/custom_systems) since that path wasn't
covered by any existing .config/.local/share mount. The emulator itself
(ti99sim-sdl) is deliberately NOT auto-built — it ships no AppImage, and
compiling it on the host risks a glibc/SDL2 mismatch against the ES-DE
container's own runtime that isn't safe to guess at blind — so this
writes the system definition (cheap, correct, always useful) and gives
manual build+placement instructions instead of a build automation I can't
verify actually runs.

Also expands the BIOS callout to mention PS2 (configured inside PCSX2's
own settings, not auto-detected from bios/) and TI-99/4A (needs a real
console ROM+GROM dump, same legal situation as any other BIOS), and
documents the MAME sample-pack-vs-ROM confusion (identical .zip naming
convention makes them indistinguishable by filename alone; samples belong
in retroarch/system/<mame-core>/samples/, not roms/mame/).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6
2026-09-02 18:04:16 +00:00
Outis 0a32ab7844 Update README to remove unnecessary exclamation
Removed redundant phrase 'Great!' from README.
2026-09-02 13:25:42 -04:00
Outis 24e59a280c Enhance README with positive remark
Updated README to include positive feedback.
2026-09-02 13:25:13 -04:00
Outis 253ee7587b Merge pull request #417 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
wolf: fix info.zip pack never actually installing (broke content matc…
2026-09-02 11:41:11 -04:00
Claude 505a342417 wolf: fix info.zip pack never actually installing (broke content matching for every core)
Confirmed live: RetroArch's file browser and directory-scan importer both
failed to recognize SNES ROMs (.sfc) even though the ROM files and the
snes9x core .so were both genuinely present and correctly mounted — the
core's own .info file (which declares supported_extensions) was never
actually installed, because the "already present, skip" check for the
info.zip pack was "is $CORES_DIR non-empty", and $CORES_DIR is always
non-empty by the time that check runs (the core .so files fill it first,
earlier in the same `cores all` run). So the info-pack fetch silently
no-op'd on every single install, fresh or not — not specific to this
laptop.

Give "info" its own real check: does $CORES_DIR actually contain any
*.info files, not just anything at all.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6
2026-09-02 15:38:51 +00:00
Outis ddfae32987 Merge pull request #416 from outis1one/claude/gitea-github-webhook-sync-7fkytg
Document the GitHub App option in the generated Gitea README
2026-09-02 08:53:31 -04:00
Claude 1b4036a0c2 Document the GitHub App option in the generated Gitea README
Adds Option B (a personal GitHub App installed with "All repositories"
access) alongside the existing per-repo webhook instructions, and
clarifies that Homepage URL and Webhook URL are separate fields on the
App creation form -- a real point of confusion when setting one up.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016oxpDzv7qfV7RDvKHp1sPD
2026-09-02 12:50:14 +00:00
Outis a49f8c3533 Merge pull request #415 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
Claude/wolf pair port conflict 7nz8qg
2026-09-01 19:41:38 -04:00
Claude c9d1eac7f2 wolf: fix unbound-variable crash on a single-drive box with no unmounted disks
Confirmed live on a laptop with only its internal drive (no second/
unmounted disk at all): the game-storage-directory picker's `local -a
_UNMT_DEV _UNMT_LABEL _UNMT_UUID` declares the arrays but, when the lsblk
scan finds zero qualifying unmounted block devices, never actually assigns
an element to any of them. Under setup.sh's `set -u`, that's enough for a
later read (`${#_UNMT_DEV[@]}`) to throw "unbound variable" even though
the arrays were properly `local -a` declared — a known bash nounset quirk
this repo has already hit and documented once before (see
vendor/ai-stack/configure-searxng-safesearch.sh). Explicit `=()`
initializers side-step it. The sibling `_CAND_*` arrays a few lines above
don't need the same fix — they always get at least one element (the home
directory option is unconditional), so they can't hit this path.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6
2026-09-01 23:41:15 +00:00
Claude 7ed376e9b7 wolf: auto-download shaders/overlays/cheats/database/autoconfig alongside cores
Extends `./manage.sh cores all` (and install_wolf()'s own cores prompt,
which calls it) to also pull the rest of what RetroArch's own Online
Updater offers — Slang shaders, overlays/bezels, cheat files, the RDB
game database, and controller autoconfig profiles — directly from the
same libretro buildbot the cores themselves come from
(buildbot.libretro.com/assets/frontend/). Confirmed live against the
real directory listing and each zip's actual internal structure (flat,
no wrapping folder) before writing the extraction paths, rather than
guessing: ~290 MB total, landing in retroarch/{shaders,overlays,cheats,
database,autoconfig}/ using RetroArch's own default paths for the three
config keys (cheat_database_path, content_database_path,
joypad_autoconfig_dir) this install leaves unset.

Thumbnails are deliberately excluded — they're hosted separately, are
per-system, and can run into many GB, so blindly grabbing "all systems"
would be a bad default; documented as a manual per-system pull via
RetroArch's own Thumbnails Updater instead.

Idempotent like the existing cores loop: skips a pack whose destination
directory already has content, unless `force` is passed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6
2026-09-01 22:29:05 +00:00
Outis 435992a4f0 Merge pull request #414 from outis1one/claude/gitea-github-webhook-sync-7fkytg
Allow typing a password when adding/resetting Authelia users
2026-09-01 15:44:57 -04:00
Claude 9d3801494a Allow typing a password when adding/resetting Authelia users
add_authelia_user() and the per-user "Reset password" action always
auto-generated a random password with no way to set a specific one.
Adds _authelia_prompt_password(), a shared masked-input prompt (same
"[Enter = auto-generate]" convention already used by backup.sh/
borg-backup.sh/koha.sh) that both call sites now use, so an admin can
type their own password or fall back to auto-generation as before.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016oxpDzv7qfV7RDvKHp1sPD
2026-09-01 19:26:29 +00:00
Outis eb794e61f9 Merge pull request #413 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
wolf: auto-fetch Dolphin's Sys folder, drop AntiMicroX, favor RetroAr…
2026-09-01 15:25:41 -04:00
Outis 5ace213bd4 Merge pull request #412 from outis1one/claude/gitea-github-webhook-sync-7fkytg
Add real-time GitHub webhook sync to Gitea
2026-09-01 15:24:34 -04:00
Claude 1d386e6a58 wolf: auto-fetch Dolphin's Sys folder, drop AntiMicroX, favor RetroArch core for GC/Wii
Confirmed live: the Dolphin libretro core needs its own 'Sys' folder
(compatibility DB + IPL data) to boot Wii titles, previously only
obtainable through a manual trip through RetroArch's Online Updater ->
Core System Files Downloader. ./manage.sh cores now fetches it
automatically (a sparse/shallow git checkout of dolphin-emu/dolphin's
Data/Sys) right after the core itself downloads, so a fresh install needs
no GUI step to get GameCube/Wii working.

Also documents the one Dolphin quirk that isn't installer-fixable: a
"This data is corrupted, delete and create a new one?" dialog with a
greyed-out OK button on a specific title (confirmed live with Mario Kart
Wii's own rksys.dat) is that game's own save data getting stuck, not a
setup defect — the fix is deleting that one file, which the README now
walks through directly instead of leaving it as a mystery.

Removes the AntiMicroX controller-combo plumbing entirely: RetroArch's own
universal hotkey binds already cover this for any core-based system
(GameCube/Wii and PS2 both now go through RetroArch's own cores rather
than standalone AppImages by default), and AntiMicroX grabbing the
controller device exclusively caused real problems (a stuck "controller
connected" screen) without enough benefit over RetroArch's native binds to
justify keeping it.

Reframes the GC/Wii/PS2 docs: RetroArch's cores are now the recommended
path (point ES-DE's Alternative Emulators at RetroArch instead of "Dolphin
(Standalone)"), with the standalone AppImages kept as a fallback and as
the only option for 3DS (Azahar has no libretro core at all).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VLX1yYKJExGSXmgUhxKQG6
2026-09-01 19:22:49 +00:00
Claude 778d06b0b8 Add real-time GitHub webhook sync to Gitea
Gitea's GitHub mirror sync previously only ran on a fixed-interval
timer. Adds an opt-in GitHub webhook receiver (small stdlib-only
Python HTTP server under its own systemd service) that verifies
GitHub's HMAC-SHA256 signature and triggers an immediate, single-repo
--pull-only sync the moment GitHub receives a push, wired through
Caddy the same way every other service in this repo is. The scheduled
timer stays in place as a safety net and still covers the Gitea ->
GitHub direction.
2026-09-01 16:27:11 +00:00
Outis 63faa9b1bd Merge pull request #411 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
Claude/wolf pair port conflict 7nz8qg
2026-09-01 11:06:39 -04:00
Claude 4199f42f70 wolf: fix wrong-architecture AppImage downloads (aarch64 picked on x86_64 hosts)
_wolf_download_emulator_appimage picked whatever release asset happened to
be first in the GitHub API's asset list among files ending in .AppImage,
with no architecture filtering. Confirmed live: pkgforge-dev's Dolphin
AppImage release lists an aarch64 build ahead of the x86_64 one, so the
downloaded file silently failed at launch with a bare "exec format error"
and no indication why — the earlier "emulator not found" symlink fix
(previous commit) got ES-DE to find the file at all, which is what
surfaced this as the next failure.

Now prefers whichever release asset's filename actually tags the host's
own architecture, falls back to an untagged asset (Azahar/PCSX2's releases
carry no arch tag and are unaffected either way), and only then falls back
to "take the first one". Also verifies the downloaded file's real ELF
architecture against the host post-download and warns loudly if it still
doesn't match, since filename tagging isn't something every release can be
trusted to get right.
2026-09-01 15:03:57 +00:00
Claude 2c51ab5faa wolf: symlink downloaded Dolphin AppImage to the name ES-DE actually looks for
ES-DE's es_find_rules.xml DOLPHIN entry only auto-detects a file literally
named Dolphin_Emulator*.AppImage under ~/Applications. pkgforge-dev's own
community-build release asset isn't named that, so the AppImage downloaded
by install_wolf() sat in emulators/ unnoticed and ES-DE reported "Couldn't
launch game, emulator not found" (%EMULATOR_DOLPHIN% unresolved) even
though the file was right there — confirmed live on a real box.

Drop a same-directory Dolphin_Emulator.AppImage symlink pointing at
whatever the real download is named, without renaming/losing the vendor
filename. Runs unconditionally (not just after a fresh download) so it
also repairs installs that grabbed the file before this fix existed.
2026-09-01 14:37:01 +00:00
Outis 6dff335ac7 Merge pull request #410 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
Fix wolf.sh: mount /home/retro/.local/share, not just .config
2026-09-01 09:52:49 -04:00
Claude 85b13d07a7 Fix wolf.sh: mount /home/retro/.local/share, not just .config
Confirmed live: Dolphin's "data is corrupted" / "could not write
to/read from Wii system memory" was ~/.local/share/dolphin-emu (the
emulated Wii NAND) not existing at all inside the container —

  ls: cannot access '/home/retro/.local/share/dolphin-emu/':
  No such file or directory

Only /home/retro/.config had a persistent mount (retro-home, added
earlier this session for the RetroArch permission-denied fix) —
/home/retro/.local/share, the other half of the XDG base directory
split many apps use (config vs. actual data), was never addressed and
started completely empty on every container launch. Any NAND state
Dolphin wrote mid-session vanished the moment that container was torn
down, which is consistent with "corrupted" rather than merely "empty"
if a session ended mid-write.

Same fix as the earlier .config mount: a new retro-home-data host
directory mounted at /home/retro/.local/share in both the esde and
retroarch app profiles (both CATALOG copies), forced to 1000:1000
ownership like the other retro-home dirs since the container's retro
user is hardcoded to that uid regardless of the host account.
2026-09-01 13:49:05 +00:00
Outis ce9a8e8c5b Merge pull request #409 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
Claude/wolf pair port conflict 7nz8qg
2026-08-31 22:45:22 -04:00
Claude bef88e654d Fix two bugs in the AntiMicroX plumbing before it ever runs
1. Glob case mismatch that would have silently no-op'd the whole
   feature: the real GitHub release asset is AntiMicroX-x86_64.AppImage
   (capitalized) — confirmed against the actual release, not assumed.
   Both the helper's own already-downloaded check and this file's own
   post-download lookup used a lowercase-only "antimicrox*.AppImage"
   glob (copied from Azahar's/PCSX2's pattern, which really are
   lowercase). Linux glob matching is case-sensitive, so _AMX_APP would
   have come back empty even after a successful download, hitting the
   "didn't produce a usable AppImage" branch and silently skipping the
   Sway launch hook with the AppImage sitting there unused.

2. Sway match criteria used app_id, which only matches native Wayland
   clients. AntiMicroX is a Qt5/X11 app running under XWayland here —
   same as ES-DE and Steam already are in this exact stock config,
   which is why their own for_window rules use [class="..."], not
   app_id. Switched to class (and title as a fallback, in case the
   exact WM_CLASS AntiMicroX registers differs), with a (?i) case-
   insensitive prefix — confirmed sway uses PCRE2 for criteria matching
   and (?i) is the documented syntax for exactly this, not assumed.

Neither bug was fatal to Wolf itself (both fail quietly rather than
crashing anything), but both would have cost real troubleshooting time
for something that looked like it should just work.
2026-09-01 02:32:45 +00:00
Claude f087984526 Add AntiMicroX plumbing for a universal controller-combo hotkey
Wires up the infrastructure for RetroArch's own hotkeys (global across
every libretro core already) to be matched by an equivalent for
Dolphin/PCSX2/Azahar, none of which support gamepad-bound hotkeys
natively (confirmed open feature requests: PCSX2/pcsx2#1082,
azahar-emu/azahar#722; Dolphin's are hardcoded to keyboard only).

AntiMicroX watches Wolf's virtual gamepad directly — a real uinput
device per Wolf's own "inputtino" docs, not a proprietary channel —
and injects whatever keyboard shortcut the focused emulator actually
expects.

Mechanism: GoW's own stock Sway config (baked into the esde/retroarch
images) has a deliberate first-line extension point,
`include /home/retro/.config/sway/custom-cfg` (confirmed by reading it
directly out of a running container). Since /home/retro/.config is
already the retro-home mount added earlier this session, writing a
file to $GAME_STORAGE_DIR/retro-home/sway/custom-cfg on the host lands
exactly there in both containers — zero changes to GoW's own image or
scripts needed.

Deliberately scoped to plumbing only: download AntiMicroX (reusing the
_wolf_download_emulator_appimage helper added for PCSX2/Dolphin), add
the Sway launch hook (floating window, not hidden, so it's reachable
through the Moonlight stream), and document the actual one-time setup
flow in the generated README. The button mapping itself, including
AntiMicroX's own per-application Auto Profile switching, is built
through its real GUI rather than a hand-authored .gamecontroller.amgp
this repo can't verify blind.

Marked experimental throughout (install prompt defaults to n, DRY-RUN
summary, README) — this is unverified against a live session.
2026-09-01 02:24:29 +00:00
Claude 1ed7fe89ea Add PCSX2 and Dolphin to wolf.sh's auto-download emulators
Factored the existing Azahar-only download block into a reusable
_wolf_download_emulator_appimage() helper (same fetch-latest-release-
and-find-.AppImage-asset logic, parameterized), then reused it for:

- PCSX2 (PS2) — officially publishes Linux AppImages via GitHub
  Releases (PCSX2/pcsx2), same pattern as Azahar.
- Dolphin (GameCube/Wii) — dolphin-emu.org's own Linux distribution
  is Flatpak-only, no official AppImage at all. Uses the well-regarded
  community AppImage build (pkgforge-dev/Dolphin-emu-AppImage)
  instead, with explicit warnings before the prompt and in the
  generated README that this is a third-party build, not an official
  Dolphin release — so the user can decide knowingly rather than this
  silently substituting an unofficial build for what looks like an
  official option.

Motivated by a live "could not write to/read from Wii system memory"
error — GameCube/Wii isn't handled by a RetroArch libretro core in any
stable way (Dolphin's libretro core is unstable for Wii specifically),
so ES-DE needs a real standalone Dolphin binary to hand those systems
off to, the same way it already does for 3DS via Azahar.

Also updated the DRY-RUN summary and the generated README's emulators
section to describe all three instead of just Azahar.
2026-08-31 23:44:24 +00:00
Outis 7dfcb8272a Merge pull request #408 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
Fix wolf.sh: mount /home/retro/.config itself, not just .config/retro…
2026-08-31 18:03:32 -04:00
Claude 0ba83212d1 Fix wolf.sh: mount /home/retro/.config itself, not just .config/retroarch
Only .config/retroarch was mounted, so Docker still had to auto-create
.config itself (one level up) as an intermediate directory for that
bind mount to attach under — same root:root mode-755 stub problem as
before, just one level higher. Confirmed live: RetroArch got past its
own config.toml write this time, but then crashed on:

  mkdir: cannot create directory '/home/retro/.config/waybar': Permission denied

(Waybar/Sway — the on-screen overlay GoW's app-runner wrapper spawns
for every app, not RetroArch-specific.)

Fix: add a second mount at /home/retro/.config itself, backed by a new
retro-home/ host directory, alongside the existing more-specific
.config/retroarch mount (Docker resolves nested/overlapping bind mounts
correctly regardless of list order). Now nothing under .config is a
Docker-auto-created stub — it's real host-backed content throughout,
so anything an app writes directly under .config (Waybar, Sway state,
RetroArch's own non-cores/shaders/overlays files) just works.

Also force retro-home/ and the existing retroarch/ dir to 1000:1000
explicitly after the general ACTUAL_USER chown — the GoW app
containers' 'retro' user is hardcoded to uid 1000 regardless of what
uid the host account installing this actually has, so relying on the
general chown alone silently breaks this fix on any box where those
don't match.
2026-08-31 21:21:53 +00:00
Outis d72c638337 Merge pull request #407 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
Fix wolf.sh update_field(): scope field search to the app's own block
2026-08-31 16:46:01 -04:00
Claude ed939e5826 Fix wolf.sh update_field(): scope field search to the app's own block
update_field() searched a blind +/-25-line window around an app's
name = '...' line to find and rewrite its mounts/env field. Once app
blocks got shorter (e.g. after collapsing a 3-line mounts array into
one line), two adjacent apps' blocks could end up close enough that
the window reached into a neighboring app's block instead — splicing
that block's own field or, worse, eating into its
[profiles.apps.runner] table header.

Confirmed live: this corrupted config.toml into invalid TOML and
crash-looped Wolf outright:

  ERROR | Unhandled exception: Error while parsing table header:
  cannot redefine existing table 'profiles.apps.runner'

Fix: bound the search to the enclosing [[profiles.apps]] block only —
walk backward from the name line to the nearest [[profiles.apps]]
header, forward to the next [[profiles.apps]] or [[profiles]] header,
and only look for the field within that range. Never crosses into a
neighboring block regardless of how short either one is.
2026-08-31 20:45:18 +00:00
Outis bc7b9c6bb0 Merge pull request #406 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
Fix wolf.sh manage.sh apps: detect installed apps regardless of inden…
2026-08-31 16:24:48 -04:00
Claude c1a97d8945 Fix wolf.sh manage.sh apps: detect installed apps regardless of indentation
INSTALLED=$(sudo grep "^    name = 'Wolf" ...) required exactly 4 leading
spaces before name = 'Wolf...' in Wolf's own generated config.toml.
Confirmed live: Wolf's TOML writer doesn't reliably indent that way, so
this came back empty even with apps clearly installed and running,
printing "No Wolf apps installed yet". That's silently wrong in two
ways: the "Already installed: ..." message under-reports, and pressing
Enter at the apps prompt ("update mounts only") falls through to the
hardcoded `steam esde` default instead of actually refreshing whatever
was already there — so a mount fix for an already-installed app (e.g.
RetroArch) never gets applied by the Enter/no-picks path at all.

Relaxed the anchor to tolerate any amount of leading whitespace,
matching the Python injector's own already-installed check a few lines
later, which never anchored on indentation to begin with.
2026-08-31 20:21:36 +00:00
Outis 0d8d87794d Merge pull request #405 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
Claude/wolf pair port conflict 7nz8qg
2026-08-31 16:11:29 -04:00
Claude 76a494bcbf Fix wolf.sh: mount whole retroarch/ dir, not just its subdirectories
The esde and retroarch app profiles (both CATALOG dict copies) mounted
three subdirectories individually:

  {games}/retroarch/cores:/home/retro/.config/retroarch/cores:rw
  {games}/retroarch/shaders:/home/retro/.config/retroarch/shaders:rw
  {games}/retroarch/overlays:/home/retro/.config/retroarch/overlays:rw

but never mounted /home/retro/.config/retroarch itself. Docker
auto-creates that missing parent directory inside the container as
root:root mode 755 (standard behavior for a bind-mount target that
doesn't already exist in the image) — the retro user (uid 1000) can
read/traverse it but not write into it. RetroArch's own entrypoint
then fails outright trying to write its default config there:

  cp: cannot create regular file '/home/retro/.config/retroarch/retroarch.cfg': Permission denied

which happens on every single launch, for both apps — confirmed live
against a real box: the container starts, RetroArch dies on that cp
within ~1s, and Wolf tears the session down (the "black screen, back
to app grid" symptom, with nothing RetroArch-specific about it).

Fix: mount the parent {games}/retroarch directory itself onto
/home/retro/.config/retroarch instead of three separate subdirectory
mounts. cores/shaders/overlays already lived as the only subdirectories
under {games}/retroarch/ on the host, so this preserves the exact same
container-side paths — but now the parent is a real bind mount with no
auto-created stub in the way, and RetroArch's other generated config
(button remaps, core options, playlists, cheats, etc.) persists across
sessions too, which the old three-mount setup silently discarded.
2026-08-31 20:09:33 +00:00
Claude 3ffcde7294 Fix gitea-github-sync.sh: stop mirroring refs/pull/* into Gitea/GitHub
Both sync directions used `git clone --bare` for the first clone and
`git push --mirror` for the push. A bare clone pulls in every ref the
remote advertises, refs/pull/*/head included — GitHub (and Gitea,
same behavior) exposes PR refs over the same smart-HTTP endpoint a
plain bare clone reads from. --mirror then pushes every local ref
verbatim, including those, and gets rejected: Gitea's server-side
hook (and GitHub's own PR-ref protection) reserves that namespace for
itself.

  remote: error: hook declined to update refs/pull/1/head
  ! [remote rejected] refs/pull/1/head (hook declined)

Fix: scope the initial clone (now git init --bare + fetch, unified
with the repeat-sync path instead of a separate git-clone branch) and
the push to an explicit refs/heads/*:refs/heads/* + refs/tags/*:refs/tags/*
refspec in both directions, matching the refspec discipline the fetch
side already had. Added a defensive cleanup (delete any
refs/pull/*, refs/merge-requests/*, refs/changes/* found in the local
bare mirror before pushing) so a repo synced before this fix
self-heals on its next run instead of tripping the same hook forever.
2026-08-31 18:51:53 +00:00
Outis a33fb0fd84 Merge pull request #404 from outis1one/claude/wolf-pair-port-conflict-7nz8qg
Add samba service: shares, dedicated users, LAN-scoped firewall
2026-08-31 14:45:39 -04:00