Drops the standalone right-click submenu (and its handler + field). Installing a
product from the console still registers its launch entries on completion, and the
Add New Product dialog's "push now" path still uses RegisterProductOnSelectedPods,
which is retained.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Launcher/build.bat now outputs to dist\TeslaLauncher\ (was TeslaLauncher\ at the
Launcher root) and produces dist\TeslaLauncher-podpkg.zip, matching Console\dist\.
- Both build scripts now zip the package themselves (Compress-Archive) instead of
leaving it as a manual step: Console/build-package.bat -> dist\TeslaConsole-pkg.zip.
- Launcher/.gitignore: ignore /dist/ (drop the obsolete /TeslaLauncher/ + staging
entries); Console already ignores /dist/.
- READMEs updated to point at dist\.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reconfigure timeout (launcher reinstall of an already-configured pod):
- The console pings each configured pod and connects on success, on a loop, and
never tore that down — so it kept hammering the pod's old IP with a stale
connection while SecureConfig tried to bring the pod up on that address, which
timed out. Only a console restart (closing all sockets) cleared it.
- DeletePod now Disconnect()s the pod's connection (closes the lingering socket)
so delete-to-reconfigure works WITHOUT a console restart.
- Reconfiguring a known pod in place now pauses that pod's ping/connect loop
(OperationInProgress) and drops its stale connection before SecureConfig, and
resumes on completion (success or failure) so it reconnects with the new key.
(StopPing kills the ping thread irreversibly, so pause via OperationInProgress.)
Note: PodInfo's static mPods registry is dead code (nothing registers), so the
real fix is the disconnect, not an unregister.
Console deployment:
- Console/install.bat: installs the console to C:\Program Files\TeslaConsole,
preps the %ProgramData%\Tesla Console data dir (Users: modify), creates a Start
Menu shortcut, and adds a per-program inbound firewall rule so it can receive
pod discovery beacons. net48 is in-box, no runtime install.
- Console/build-package.bat: publishes the console (net48 framework-dependent) to
dist\TeslaConsole\App and assembles the package with install.bat.
74 tests green; the pod-config fix is UI/network behavior, validate on a pod.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
RIOJoy (the cockpit RIO → virtual-gamepad feeder; separate net48 repo) is now an
installable/launchable product in Console/RedPlanet/Apps.xml. Its dist zip is
already TeslaConsole-shaped (postinstall.bat + RIOJoy\ → extracts to C:\Games, the
launcher runs postinstall.bat as SYSTEM to install ViGEmBus + register auto-start),
so this is the only change needed on the TeslaSuite side.
- Launch entry exe C:\Games\RIOJoy\app\RioJoy.Tray.exe, autoRestart=false (the
postinstall HKLM Run entry owns startup; the catalog entry is for registration +
manual restart from the console).
- CatalogTests: bumped the count guard to 4 products / 6 entries and added a
byte-exact LaunchData check for the RIOJoy entry. 74 tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Root README: launcher is .NET Framework 4.8 (was .NET 6/x86); RPC is framed
JSON (was BinaryFormatter); added Contract/ + SecureConfig/; dropped the
now-resolved "known duplication" warning; corrected the lib/*.dll note
(TeslaConsoleLaunchLib/TeslaSecureConfiguration are source-built, kept only as
test baselines); added a short history section.
- Console README: Contract is net48-only; Launcher targets net48.
- Launcher README: net48 framework-dependent (was net8/x64 self-contained);
needs .NET Framework 4.8 (built into Windows), no bundled runtime.
- DiffTests README: original 4.11.3.37076 vs recovered 4.11.4.x (no longer share
identity); noted version-insensitive comparison + the new protocol/crypto guards.
- Removed Launcher/assets/MEMORY.md (stale leftover dev-notes, superseded by the
README and now-moot post-BinaryFormatter).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Launcher Service + Agent moved from net8/x64 self-contained to net48
framework-dependent; Tesla.Contract is now net48-only (single TFM across the
suite). Package drops from ~91 MB zipped to ~1.6 MB. Tested OK end-to-end on a
pod computer.
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>
build.bat was broken by the contract extraction: it staged the loose Launcher
.cs files into temp folders and published from there, but the projects now have
a ProjectReference to ..\Contract\Tesla.Contract.csproj which cannot resolve from
a temp dir. Publish the projects IN PLACE instead, and target net8 / win-x64
(self-contained single-file) to match the runtime/arch uplift. The resulting
TeslaLauncher\ package (Service\ + Agent\ + install.bat) installs on a pod with
no .NET runtime prerequisite.
- Launcher/README.md: correct net6->net8, x86->x64, BinaryFormatter->framed JSON,
and note wire types now come from ../Contract.
- Launcher/.gitignore: ignore the TeslaLauncher-*.zip deployment package.
- Console/.gitignore: ignore the published TeslaConsole-app\ package + its zip
(framework-dependent net48 console build for running against a test pod).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Make the Console<->Launcher system source-built and modern now that the console
is under our control and the WinXP-era pods are gone.
Contract extraction (Contract/Tesla.Contract.csproj):
- One multi-targeted (net48;net8.0-windows) source project for the RPC contract,
replacing the vendored TeslaConsoleLaunchLib.dll and the hand-synced Tesla.Net
replica in Launcher/LaunchModels_Shared.cs. Emits assembly TeslaConsoleLaunchLib.
SecureConfig extraction (SecureConfig/Tesla.SecureConfig.csproj):
- net48 source of the first-boot provisioning protocol (UDP beacons, OFB crypto,
RSA key exchange), replacing the vendored TeslaSecureConfiguration.dll.
Remove BinaryFormatter from the wire (RCE sink + the reason net6 was pinned):
- Console<->Launcher RPC is now length-prefixed System.Text.Json frames
(Contract/PodRpcProtocol.cs) over the unchanged OFB transport; dispatch by
method name. Deleted the SerializationBinder / MethodInfoProxy machinery.
- Console-local BinaryFormatter (Site config, mission replays) intentionally
retained: local net48 file I/O, not the network surface.
Runtime modernization:
- Launcher Service + Agent: net6 -> net8, win-x86 -> win-x64 (all pods are
64-bit Win10). Kept the SHA1-default PBKDF2 (Console key-derivation compat)
with SYSLIB0041 suppressed and documented.
Tests: differential suite now 73 green. Added SecureConfigCompatTests (OFB
ciphertext byte-identical to the vendored DLL) and PodRpcProtocolTests (JSON
round-trip of every request/response shape); removed the now-obsolete
BinaryFormatter byte-identity guard.
Build hygiene: per-project obj dirs (Launcher/Directory.Build.props) fix a
NuGet restore collision between the two Launcher projects sharing one folder.
NOT runtime-verified against a live pod.
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>