RIOJoy lifecycle is now owned by the console + launcher (the auto-start Run entry
was removed on the RioJoy side): Apps.xml autoRestart false -> true, so the
launcher starts RIOJoy and keeps it alive. Safe with uninstall — the watcher only
relaunches a still-tracked process, and uninstall's kill untracks it first.
Uninstall now physically removes the product (was unregister-only):
- Agent CmdUninstallApp: after kill + unregister, reports the product's
C:\Games\<dir> to clean up — but only if no remaining registered launch entry
still uses that folder (orphan check keeps multi-entry products like Red Planet's
GameClient/LC/MR intact until the last entry is removed).
- Service (SYSTEM): on UninstallApp, runs <dir>\pre-uninstall.bat if present
(RIOJoy's removes ViGEmBus + config) then deletes the directory, on a background
thread so it can't trip the Console's RPC timeout. Path-guarded to only ever
delete a proper subdirectory of C:\Games. Logged to podconf.log.
74 tests green; the cleanup path is pod-behavior, not unit-tested here.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Converts the Launcher Service + Agent from net8/win-x64 self-contained to net48
framework-dependent, and makes Tesla.Contract net48-only (drops multi-targeting).
Both consumers (Console + Launcher) are now a single TFM.
Code changes for net48 (the only net8/netstandard2.1 APIs in use):
- RandomNumberGenerator.Fill -> RandomNumberGenerator.Create().GetBytes (3x)
- TcpListener.AcceptTcpClientAsync(ct) -> AcceptTcpClientAsync() + stop-on-cancel
- byte[].AsSpan().SequenceEqual -> Linq SequenceEqual (no System.Memory) (2x)
- PipeStream.Write(byte[]) / WriteAsync(byte[],ct) -> explicit (buf,0,len[,ct])
- Math.Clamp -> Math.Max/Min
The generic host (Microsoft.Extensions.Hosting 8.x + UseWindowsService) runs on
net48 unchanged. build.bat/install.bat updated for the folder-of-DLLs deploy;
solution platform reverted x64 -> AnyCPU.
RESULT — package size: ~3.7 MB on disk / 1.58 MB zipped, vs ~213 MB / 91 MB for
the net8 self-contained build (~50-58x smaller). net48 ships in Win10/11 so no
runtime prerequisite. 73 tests green; NOT re-validated on a live pod.
Spike branch for evaluation — do not merge without a pod re-test.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Console AssemblyVersion/AssemblyFileVersion 4.11.3.37076 -> 4.11.4.1. The
recovered console is no longer a byte-faithful copy of the original baseline;
it is the modernized 4.11.4.x line.
- Launcher Service + Agent Version -> 4.11.4.1 (unified suite version). The Agent
tray menu header now shows the running version ("Tesla Launcher Agent v4.11.4.1").
- Differential tests: the identity guard now expects the original at 4.11.3.37076
and the recovered at 4.11.4.1 (not identical); the public-member surface check
strips Version= stamps before comparing, since generic-argument signatures embed
the assembly version (we compare type names, not versions). 73 tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Agent only opened the on-screen passcode splash when IsMachineConfigured()
was false (Ethernet adapter on DHCP). But during SecureConfig the Service assigns
a TEMPORARY static IP to the adapter so it can broadcast — which flips
IsMachineConfigured() to true. So an Agent starting at auto-login (in the
SecureConfig wait window) saw a "configured" adapter and skipped the splash
entirely; the Request ID / Passphrase only reached the log and the COM2 plasma
display, never the screen.
Gate the splash on the configuring.json file the Service writes (before the temp
IP) as well as the DHCP check, and make the splash dismiss robustly when
SecureConfig finishes (file gone after being seen, or the machine becomes
configured). The COM2 plasma path in the Service was already correct.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-locate the two cockpit-pod projects into a single repository:
- Console/ : TeslaConsole, the net48 WinForms operator console (decompiled
reconstruction) plus its differential + catalog test suite.
- Launcher/ : TeslaLauncher, the net6 pod-side Service + Agent rewrite.
Adds a combined TeslaSuite.sln, root README documenting the shared wire
contract (and its current duplication, the main follow-up), and a root
.gitignore. Histories were not preserved per request; this is a fresh start
from the current working state of both projects.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>