Skip to content

Commit 2f660b9

Browse files
Merge main into master after PR 63
2 parents c26e3ed + 8eb29ce commit 2f660b9

527 files changed

Lines changed: 42762 additions & 1703 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Normalize line endings
2+
* text=auto
3+
4+
# Force CRLF for Windows-specific files
5+
*.bat text eol=crlf
6+
*.ps1 text eol=crlf
7+
8+
# Binary files
9+
*.dll binary
10+
*.exe binary
11+
*.zip binary
12+
*.png binary
13+
*.ico binary

.github/pull_request_template.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
## Summary
2+
3+
-
4+
5+
## Control-Layer / Install Safety Checklist
6+
7+
- [ ] `dotnet build LSPDFRManager.sln`
8+
- [ ] `dotnet test LSPDFRManager.Tests/LSPDFRManager.Tests.csproj`
9+
- [ ] `dotnet test`
10+
- [ ] Architecture guards pass and any new side-effect boundary has a focused test.
11+
- [ ] ViewModels delegate orchestration to controllers/commands; no direct install enqueue from ViewModels.
12+
- [ ] Passive events only stage/update status; installs require explicit user action.
13+
- [ ] Installer safety sequence is unchanged: safe path, create directory, copy stream, then rollback entry.
14+
- [ ] Singleton event subscriptions are detached or scoped.
15+
- [ ] SharpCompress usage stays behind archive adapters.
16+
- [ ] Docs/release notes use relative paths, not machine-local absolute paths.
17+
18+
## UI Smoke
19+
20+
Record one:
21+
22+
- `UI smoke run: done by <name> on <yyyy-mm-dd>`
23+
- `UI smoke run: not run: no WPF/WebView UI available`
24+
25+
Checklist: [docs/ui-smoke-pr-check.md](../docs/ui-smoke-pr-check.md)
26+
27+
## Reviewer Focus
28+
29+
- Search for `Enqueue`, installer calls, passive-event side effects, event subscriptions, and archive-library leakage.

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ publish/
2121
publish*/
2222
*.zip
2323
*.lscache
24+
.lscache/
25+
artifacts/
26+
Releases/
27+
LSPDFRManager-v*/
2428

2529
## OS
2630
.DS_Store
@@ -38,6 +42,7 @@ release-worktree/
3842
## Release artifacts (built locally, uploaded via GitHub Actions)
3943
release-package/
4044
zip-smoke/
45+
support-bundle*.zip
4146

4247
## Internal dev/planning docs (not for public repo)
4348
PHASE_C_STREAMING.md
@@ -46,3 +51,8 @@ REFACTOR_SUMMARY.md
4651
## Test artifacts
4752
*.log
4853
test.log
54+
TestResults/
55+
publish-smoke/
56+
57+
## Internal planning (not for public repo)
58+
FEATURES_TO_IMPLEMENT.md

App.xaml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,24 @@
4646
<DataTemplate DataType="{x:Type vm:OivViewModel}">
4747
<views:OivView/>
4848
</DataTemplate>
49+
<DataTemplate DataType="{x:Type vm:DevDiagnosticsViewModel}">
50+
<views:DevDiagnosticsView/>
51+
</DataTemplate>
52+
<DataTemplate DataType="{x:Type vm:PatrolReadinessDashboardViewModel}">
53+
<views:PatrolReadinessDashboardView/>
54+
</DataTemplate>
55+
<DataTemplate DataType="{x:Type vm:SafeModeViewModel}">
56+
<views:SafeModeView/>
57+
</DataTemplate>
58+
<DataTemplate DataType="{x:Type vm:SetupWizardViewModel}">
59+
<views:SetupWizardView/>
60+
</DataTemplate>
61+
<DataTemplate DataType="{x:Type vm:CleanupViewModel}">
62+
<views:CleanupView/>
63+
</DataTemplate>
64+
<DataTemplate DataType="{x:Type vm:ReactPreviewViewModel}">
65+
<views:ReactPreviewView/>
66+
</DataTemplate>
4967
</ResourceDictionary>
5068
</Application.Resources>
5169
</Application>

App.xaml.cs

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Windows;
22
using LSPDFRManager.Core;
33
using LSPDFRManager.Domain;
4+
using LSPDFRManager.LocalApi;
45
using LSPDFRManager.Services;
56
using LSPDFRManager.ViewModels;
67

@@ -21,6 +22,13 @@ protected override void OnStartup(StartupEventArgs e)
2122
ex.Handled = false;
2223
};
2324

25+
// Start local API in-process (non-blocking; React UI nav waits on PortTask)
26+
_ = Task.Run(async () =>
27+
{
28+
try { await LocalApiHost.StartAsync(); }
29+
catch (Exception ex) { AppLogger.Error("[LOCALAPI] Failed to start", ex); }
30+
});
31+
2432
try
2533
{
2634
base.OnStartup(e);
@@ -38,6 +46,12 @@ protected override void OnStartup(StartupEventArgs e)
3846
}
3947
}
4048

49+
protected override void OnExit(ExitEventArgs e)
50+
{
51+
base.OnExit(e);
52+
_ = LocalApiHost.StopAsync();
53+
}
54+
4155
private static void ValidateStartup()
4256
{
4357
var issues = new List<string>();
@@ -56,15 +70,31 @@ private static void ValidateStartup()
5670
}
5771

5872
var gtaPath = AppConfig.Instance.GtaPath;
59-
if (string.IsNullOrWhiteSpace(gtaPath) || !Directory.Exists(gtaPath))
60-
{
61-
issues.Add($"GTA V installation folder not found:\n {gtaPath}\n Open Settings to set the correct path.");
62-
}
63-
else
73+
var wizardWillRun = AppConfig.Instance.ShowSetupWizardOnStartup
74+
|| string.IsNullOrWhiteSpace(gtaPath);
75+
76+
if (!wizardWillRun)
6477
{
65-
var exePath = Path.Combine(gtaPath, "GTA5.exe");
66-
if (!File.Exists(exePath))
67-
issues.Add($"GTA5.exe was not found in:\n {gtaPath}\n Verify Settings points at the GTA V installation folder.");
78+
if (!Directory.Exists(gtaPath))
79+
{
80+
issues.Add($"GTA V installation folder not found:\n {gtaPath}\n Open Settings to set the correct path.");
81+
}
82+
else
83+
{
84+
if (LspdfrInstallLocator.FindGtaExe(gtaPath) is null)
85+
issues.Add($"GTA V executable not found in:\n {gtaPath}\n Verify Settings points at the GTA V installation folder.");
86+
87+
var writeProbe = Path.Combine(gtaPath, ".lspdfrmanager_write_test");
88+
try
89+
{
90+
File.WriteAllText(writeProbe, "");
91+
File.Delete(writeProbe);
92+
}
93+
catch
94+
{
95+
issues.Add($"GTA V folder is not writable:\n {gtaPath}\n The app must run as Administrator to install mods into a protected directory.");
96+
}
97+
}
6898
}
6999

70100
AddDiskSpaceIssueIfNeeded(issues, AppDataPaths.Root, "App data");

BASELINE_VERIFICATION.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# Baseline Verification — React Migration
2+
3+
**Date/time:** 2026-05-19
4+
**Branch:** main
5+
**HEAD commit:** `53ee06f` — fix(logging): write errors to logs/errors.log in app directory
6+
**Version:** v3.7.17
7+
8+
---
9+
10+
## Working Tree Status
11+
12+
Clean. Only untracked files present (no modified tracked files):
13+
14+
```
15+
Untracked files:
16+
REACT_MIGRATION_ANALYSIS.md ← migration docs, not part of app
17+
REACT_MIGRATION_PLAN.md ← migration docs, not part of app
18+
"e unexpected files are present." ← pre-existing untracked artifact
19+
```
20+
21+
No staged changes. No modified source files. Safe to begin migration work.
22+
23+
---
24+
25+
## Commands Run
26+
27+
### 1. `dotnet restore LSPDFRManager.sln`
28+
29+
**Result: PASS**
30+
31+
```
32+
All projects are up-to-date for restore.
33+
```
34+
35+
Warnings (pre-existing, non-blocking):
36+
- `NU1902: Package 'SharpCompress' 0.38.0 has a known moderate severity vulnerability`
37+
This advisory was present before this session began and is documented in project memory as a known non-blocker.
38+
39+
---
40+
41+
### 2. `dotnet build LSPDFRManager.sln --configuration Release --no-restore`
42+
43+
**Result: PASS — 0 errors**
44+
45+
```
46+
Build succeeded.
47+
6 Warning(s)
48+
0 Error(s)
49+
Time Elapsed 00:00:04.36
50+
```
51+
52+
Outputs:
53+
- `LSPDFRManager.Api``bin\Release\net8.0\LSPDFRManager.Api.dll`
54+
- `LSPDFRManager``bin\Release\net8.0-windows\LSPDFRManager.dll`
55+
- `LSPDFRManager.Tests``LSPDFRManager.Tests\bin\Release\net8.0-windows\LSPDFRManager.Tests.dll`
56+
57+
Warnings (all pre-existing):
58+
59+
| Warning | File | Notes |
60+
|---------|------|-------|
61+
| `NU1902` SharpCompress vulnerability | Both projects | Known advisory; non-blocker |
62+
| `CS0219` variable assigned but never used (`failureRaised`) | `InstallIntegrationTests.cs:221` | Pre-existing test warning |
63+
| `CS8602` dereference of possibly null | `StreamingBufferTests.cs:47` | Pre-existing test warning |
64+
| `CS8605` unboxing possibly null | `StreamingBufferTests.cs:47` | Pre-existing test warning |
65+
| `xUnit2029` use DoesNotContain instead of Empty | `EupBackupEditorTests.cs:439` | Pre-existing xUnit analyzer suggestion |
66+
67+
---
68+
69+
### 3. `dotnet test LSPDFRManager.Tests\LSPDFRManager.Tests.csproj --configuration Release --no-build`
70+
71+
**Result: PASS — 914/914 tests passed**
72+
73+
```
74+
Total tests: 914
75+
Passed: 914
76+
Failed: 0
77+
Skipped: 0
78+
Total time: 10.7260 Seconds
79+
0 Error(s)
80+
```
81+
82+
> Note: Previous recorded baseline was 878 tests (v3.7.16 / v3.7.17). The count is now 914 — additional tests were added in commits since the last recorded snapshot. All 914 pass.
83+
84+
---
85+
86+
## Summary of Warnings / Failures
87+
88+
| Item | Type | Severity | Action |
89+
|------|------|----------|--------|
90+
| `NU1902` SharpCompress advisory | Dependency warning | Pre-existing, non-blocking | No action needed |
91+
| `CS0219` unused variable | Code warning | Pre-existing | No action needed |
92+
| `CS8602` / `CS8605` null warnings | Code warning | Pre-existing | No action needed |
93+
| `xUnit2029` | Analyzer suggestion | Pre-existing | No action needed |
94+
95+
No new warnings introduced. No errors. No failing tests.
96+
97+
---
98+
99+
## Safe to Proceed to Milestone 1?
100+
101+
**Yes.** The repository is in a fully clean, passing state.
102+
103+
- 0 build errors
104+
- 914/914 tests passing
105+
- No modified tracked source files
106+
- Pre-existing warnings are known and non-blocking
107+
108+
---
109+
110+
## Recommended Next Step
111+
112+
Begin **Milestone 1**: Scaffold `LSPDFRManager.LocalApi` — a new ASP.NET Core Minimal API project that will serve as the local management API for the React frontend.
113+
114+
Per `REACT_MIGRATION_PLAN.md` Milestone 1:
115+
1. Create `LSPDFRManager.LocalApi/` as a new `Microsoft.NET.Sdk.Web` project targeting `net8.0`.
116+
2. Add minimal `Program.cs` with a `/health` endpoint.
117+
3. Add `LocalhostOnlyMiddleware` (reject non-`127.0.0.1` Host headers).
118+
4. Add to `LSPDFRManager.sln`.
119+
5. Verify `dotnet build` — 0 errors.
120+
6. Verify `dotnet test` — all 914 tests still pass.
121+
122+
> **Important prerequisite for Milestone 2 (shared library extraction):** `Domain/`, `Services/`, and `Core/` currently live inside `LSPDFRManager.csproj` which targets `net8.0-windows`. For `LSPDFRManager.LocalApi` (targeting `net8.0`) to reference these, they must be extracted to a new `LSPDFRManager.Core` class library project. This is the highest-risk structural change and should be planned carefully before execution.

0 commit comments

Comments
 (0)