Skip to content

feat: diagnostics screen with a copyable report - #159

Merged
lippdev merged 1 commit into
mainfrom
feat/diagnostics
Oct 19, 2026
Merged

lippdev merged 1 commit into
mainfrom
feat/diagnostics

Conversation

@lippdev

@lippdev lippdev commented Oct 19, 2026

Copy link
Copy Markdown
Owner

What

A Diagnóstico / Diagnostics expander in Settings → "Atalho, ajuda e dados", next to "Test controller". It shows, read-only, a plain-text report with Atualizar / Refresh and Copiar relatório / Copy report buttons:

  • App version, install kind (installed/portable) and update channel (stable / test build / stable receiving test versions), Windows edition/release/build, .NET runtime.
  • Displays from MonitorService: name, resolution @ Hz, HDR on/off/unsupported (CCD), and marks for the game screen, the screens hidden in console mode, primary and off.
  • Audio outputs (fresh AudioService), marking the Windows default and the one chosen in the app.
  • Controllers (RawGameController): name, VID:PID and type (Xbox / PlayStation / Nintendo / Other, plus "gamepad").
  • Steam, Playnite, RTSS, ControlFS: path and file version, or "not found"; the configured launcher (FullscreenMode).
  • The last 50 lines of consolemode.log (read with FileShare.ReadWrite, since AppLog may be writing).

Why

Issues about screens/audio/controllers usually need several rounds of questions. One button that copies everything the app sees makes a bug report self-contained.

How

  • Services/DiagnosticsReport.cs (pure, linked in the test project): simple records (DiagnosticsSystem, DiagnosticsDisplay, DiagnosticsAudio, DiagnosticsController, DiagnosticsApp) → text. A null section prints unavailable, an empty one (none). Everything goes through Redact: C:\Users\<name>\ → C:\Users\…\, dpapi: blobs (SecretProtector), PEM private keys (the ADB key) and token=/password=/pairingKey:/Authorization:-style values.
  • ViewModels/MainViewModel.Diagnostics.cs: gathers the data in Task.Run, each section in its own try/catch (logged in Portuguese). Opening the expander loads it the first time.
  • Extension point for controller extras: DiagnosticsController(string Name, string Type, string? Detail = null); Detail is printed after the type (e.g. a battery level) and is filled in MainViewModel.CollectControllers(). Battery isn't implemented here.
  • The report text itself is English on purpose (it's read by whoever answers the issue); the card, description and buttons are localized in all six catalogs.
  • Changelog entries in both files; manual checks in docs/TESTING.md.

Testing

  • dotnet test tests/ConsoleMode.Tests/ConsoleMode.Tests.csproj: all green, including new DiagnosticsReportTests (formatting, unavailable/empty sections, log tail, path and secret redaction) and the localization tests.
  • The app build (WinUI, Windows-only) was left to CI. Screens, HDR, audio and controllers need a real PC: see the new "Diagnóstico" section in docs/TESTING.md.

🤖 Generated with Claude Code

Settings gets a Diagnostics card that shows what the app sees on this PC
(version and channel, Windows and .NET, screens with HDR and roles, audio
outputs, controllers, Steam/Playnite/RTSS/ControlFS, the end of the log)
and copies it as a plain-text report. Data is gathered off the UI thread;
a section that throws reads "unavailable". The report is built and
redacted (user name in paths, keys and tokens) in DiagnosticsReport, which
is unit tested.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

The path redaction misses UNC profile paths, so the copied report can expose a Windows account name on systems using roaming/network profiles.

Reviewed changes The initial review covers the diagnostics screen, its collectors and report redaction, localization, documentation, and formatter tests.

  • Diagnostics collection Adds an expandable Settings card that gathers app/runtime, display, audio, controller, launcher, and recent log information off the UI thread.
  • Report formatting and privacy Adds a plain-text report with section-level unavailable/empty states, user-path and secret redaction, and unit tests.
  • Supporting updates Adds localized UI strings, changelog entries, and manual validation steps.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using gpt-6-luna | 𝕏

if (!any) sb.AppendLine("(none)");
}

private static readonly Regex UserPath = new(@"(?i)\b([a-z]:[\\/]+(?:users|documents and settings)[\\/]+)[^\\/\r\n""']+", RegexOptions.Compiled);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only matches drive-letter profile paths. A roaming or network profile can produce a UNC path such as \\server\Users\alice\... in an app path or log line, leaving the account name visible in the copied report despite the privacy guarantee. Please redact UNC Users / Documents and Settings profile prefixes too and cover that form with a test.

Technical details
# UNC profile paths retain account names

## Affected sites
- `src/ConsoleMode/Services/DiagnosticsReport.cs:108` — `UserPath` requires a drive letter, so UNC profile paths are not matched.
- `tests/ConsoleMode.Tests/DiagnosticsReportTests.cs` — add coverage for a UNC path and verify only the profile name is replaced.

## Required outcome
- Redact the account component in both drive-letter and UNC profile paths before the report is displayed or copied.

@lippdev
lippdev merged commit d7aa511 into main Oct 19, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant