Skip to content

fix(android): diagnostic log sharing and whitelist black-screen fix#232

Open
hvkeyn wants to merge 59 commits into
InvisibleManVPN:masterfrom
hvkeyn:fix/android-logging-whitelist-blackscreen
Open

fix(android): diagnostic log sharing and whitelist black-screen fix#232
hvkeyn wants to merge 59 commits into
InvisibleManVPN:masterfrom
hvkeyn:fix/android-logging-whitelist-blackscreen

Conversation

@hvkeyn
Copy link
Copy Markdown

@hvkeyn hvkeyn commented May 21, 2026

Summary

  • Добавлено расширенное диагностическое логирование: ротация diagnostic.log (до 1 МБ + архив .1), глубокий вывод вложенных исключений, методы ReadAll / ClearAll.
  • На Android в настройках появился блок Logs and diagnostics с кнопками «Поделиться логом», «Сохранить на устройство» и «Очистить лог»; лог можно отправить через почту, Telegram и т.д. через системный chooser.
  • Установлены глобальные обработчики необработанных исключений (C# + Java) и логирование ошибок загрузки Avalonia XAML — чтобы чёрный экран при сбое давал диагностику, а не молчал.
  • Исправлена проблема с белым списком (ONLY_SELECTED_APPS): если ни одно приложение не попало в whitelist, VPN больше не поднимается с неявным «все приложения через VPN»; пользователь получает понятную ошибку.

Root cause (whitelist black screen)

При режиме ONLY_SELECTED_APPS, если список разрешённых пакетов пуст (ничего не выбрано или выбранные приложения не установлены), Android VpnService.Builder без AddAllowedApplication маршрутизирует весь трафик через VPN. Это приводило к нестабильному поведению и зависанию UI (чёрный экран), которое сохранялось после перезагрузки из-за сохранённых настроек.

Test plan

  • Установить APK из publish-android/logging-arm64/ на физическое устройство (Samsung).
  • Включить белый список без выбранных приложений — убедиться, что VPN не стартует и показывается понятная ошибка, UI остаётся рабочим.
  • Включить белый список с 1–2 реальными приложениями — VPN стартует, трафик идёт только для выбранных.
  • Открыть Settings → Logs and diagnostics → «Поделиться логом» — chooser открывается, файл прикрепляется.
  • «Сохранить на устройство» — файл появляется в Downloads/InvisibleGorillaXRay/.
  • «Очистить лог» — размер лога обнуляется.
  • Смоделировать сбой (если возможно) — убедиться, что исключение попало в diagnostic.log.
  • dotnet build для Core, Mac, Linux, Android — без новых ошибок.

hvkeyn and others added 30 commits February 17, 2026 03:39
Rebrand:
- Rename project from InvisibleMan-XRay to InvisibleGorilla-XRay
- Update all namespaces (InvisibleManXRay -> InvisibleGorillaXRay)
- Rename solution, csproj, directories, and core class files
- Update assembly name, product, company, copyright metadata
- Update all window titles, localization strings (en-US, ru-RU, fa-IR)
- Update XAML resource keys (Icon.InvisibleGorilla)
- Update Go module path and README/Language.md/LICENSE

Bug Fixes:
- Fix memory leak in XRayCoreWrapper: IntPtr from Marshal.AllocHGlobal
  was never freed, added try/finally with Marshal.FreeHGlobal
- Fix event handler leak in App.xaml.cs: lambda unsubscription was
  creating new instances instead of removing originals
- Fix resource leaks: RegistryKey, StreamReader/Writer, NamedPipeStream,
  Process objects now properly disposed with using/Dispose()
- Fix JsonUtility.Find: Single() replaced with FirstOrDefault() to
  prevent InvalidOperationException; added null-safety
- Fix JsonUtility.IsJsonValid: JsonDocument now disposed with using
- Fix Go wrapper: HTTP response body now closed after connection test
- Add null-safety guards in FileUtility and XRayCoreWrapper

New:
- Add build.ps1: one-command build script that auto-installs Go and
  .NET SDK from official sources (no winget/package manager needed)
- Rewrite README.md with architecture overview, feature list, build
  options table, and tech stack documentation

Co-Authored-By: Cursor <cursoragent@cursor.com>
…URLs

- Fix critical proxy issue: use INTERNET_OPTION_PER_CONNECTION_OPTION API to update DefaultConnectionSettings blob (browsers ignore registry-only changes)
- Fix startup order: start xray-core first, wait for port active, then enable system proxy (prevents dead-port race condition)
- Add WM_SETTINGCHANGE broadcast for instant browser proxy pickup
- Add proxy cleanup on crash/exit (UnhandledException + ProcessExit)
- Add ProxyOverride for localhost to prevent proxy loops
- Add diagnostic logging system for troubleshooting
- Replace human icons with gorilla design in Icons.xaml
- Update application icon (Icon.ico) with gorilla branding
- Update GitHub repository URLs to hvkeyn/InvisibleGorilla-XRayClient
- Update Go module path and README

Co-authored-by: Cursor <cursoragent@cursor.com>
- Fix UI hang: replace blocking SendMessageTimeout with async SendNotifyMessage for WM_SETTINGCHANGE broadcast
- Move DisableMode off UI thread (Task.Run) to prevent freeze on Stop button
- Update README: add fork improvements table, troubleshooting section, badges, acknowledgments

Co-authored-by: Cursor <cursoragent@cursor.com>
img new upload
Rebrand to InvisibleGorilla + Fix critical VPN proxy routing and UI hang
- Add automatic GCC/MinGW installation via w64devkit when C compiler
  is missing or incompatible (GCC 15+ breaks Go cgo)
- Pin w64devkit to v2.0.0 (GCC 14.2.0) for Go cgo compatibility
- Add Invoke-Download with real-time progress bar (percentage, size,
  speed, ETA) using WebClient async events
- Add Start-ProcessWithSpinner for visual feedback during installs
- Add download size verification with MinimumSize parameter to detect
  truncated downloads from CDN issues
- Add automatic retry (3 attempts) with Invoke-WebRequest fallback
- Replace all Invoke-WebRequest calls with Invoke-Download for
  consistent UX across Go, GCC, .NET SDK, geo files, and TUN downloads

Co-authored-by: Cursor <cursoragent@cursor.com>
- Add automatic GCC/MinGW installation via w64devkit when C compiler
  is missing or incompatible (GCC 15+ breaks Go cgo)
- Pin w64devkit to v2.0.0 (GCC 14.2.0) for Go cgo compatibility
- Add Invoke-Download with real-time progress bar (percentage, size,
  speed, ETA) using WebClient async events
- Add Start-ProcessWithSpinner for visual feedback during installs
- Add download size verification with MinimumSize parameter to detect
  truncated downloads from CDN issues
- Add automatic retry (3 attempts) with Invoke-WebRequest fallback
- Replace all Invoke-WebRequest calls with Invoke-Download for
  consistent UX across Go, GCC, .NET SDK, geo files, and TUN downloads
macOS build script (Sequoia 15.7+, auto-installs deps)
- Add gorilla-xray CLI binary (cmd/gorilla-xray/main.go) - standalone xray-core proxy client for macOS, built as a regular Go executable

- Update build-macos.sh to produce both XRayCore.dylib (c-shared lib) and gorilla-xray (CLI binary) in a single build step

- Update distribution bundle to include the CLI binary with usage docs

- Update README with CLI usage examples and macOS proxy setup commands

- Update .gitignore for build artifacts (gorilla-xray, *.dylib)

Co-authored-by: Cursor <cursoragent@cursor.com>
Introduce cross-platform architecture with three projects:
- InvisibleGorilla.Core: shared library with platform-agnostic logic
  (handlers, services, models, utilities) and DI-based abstractions
  for proxy, tunnel, deep links, and startup settings
- InvisibleGorilla-XRay.Mac: full Avalonia UI macOS client with
  identical interface and functionality to the Windows WPF version
- Updated build-macos.sh to build Avalonia GUI and produce .app bundle

macOS-specific implementations:
- Proxy via networksetup (HTTP/HTTPS)
- TUN mode via utun device + tun2socks with route/DNS management
- LaunchAgent for startup, Unix domain sockets for IPC
- Deep link handling (invxray:// URL scheme)
- Info.plist with CFBundleURLTypes and Retina support

All three projects (Core, Mac, WPF) build with 0 errors, 0 warnings.

Co-authored-by: Cursor <cursoragent@cursor.com>
- Add all missing localization keys (WindowTitle variants, error messages,
  config actions) to both en-US and ru-RU dictionaries
- Fix MacLocalizationHandler to remove old dictionary before adding new one
  on language switch, preventing duplicate/stale entries
- Fix MainWindow close: minimize when VPN is active instead of hiding
  (which caused unrecoverable hang), graceful shutdown otherwise
- Implement MacNotifyHandler with Avalonia TrayIcon (menu bar icon)
  providing Open, Proxy/TUN mode switch, About, and Quit actions
- Add right-click context menu to config items in ServerWindow:
  Select, Check (ping test with async latency display), Share (copy path),
  Log (open log file), Delete

Co-authored-by: Cursor <cursoragent@cursor.com>
feat(macos): port GUI to macOS using Avalonia UI
…sues


- Fix GetTerm() to fallback to Avalonia TryFindResource when manual
  terms dictionary is empty (ResourceDictionary iteration unreliable)
- Replace CanResize="False" with Min/Max size constraints on all windows
  to restore macOS minimize button functionality
- Change MainWindow close behavior to Hide (standard macOS UX),
  exit only via Quit in tray menu; async cleanup with 3s timeout
- Add UpdateUI() call after ServerWindow/SettingsWindow dialogs close
  to ensure config changes reflect immediately on main screen
- Replace context-menu-only config actions with visible button row:
  Select, Check (ping), Share (copy path), Log, Delete
- Generate app icon at runtime from Icon.InvisibleGorilla DrawingBrush
  for Window.Icon and TrayIcon via RenderTargetBitmap
- Add .icns generation to build-macos.sh using Python3 + sips + iconutil,
  add CFBundleIconFile to Info.plist for dock icon
fix(macos): resolve localization, window lifecycle, UI interaction issues
- Load config via loadConfig() before passing to core.Test() in Check
  button handler (was passing raw file path, causing Go native SIGABRT)
- Remove Core.Stop() from CleanupBeforeExit to prevent native Go abort
  on shutdown; DisableMode() alone handles proxy/tunnel cleanup safely
- Add explicit CanResize="True" on all windows to ensure macOS enables
  NSWindowStyleMaskMiniaturizable for the minimize traffic light button
fix(macos): fix Check crash, Quit hang, and minimize button
- Replace PointerPressed with Tapped on "Manage server configuration"
  link to prevent pointer capture from trapping all subsequent clicks
  and re-opening the ServerWindow in an infinite loop
- Add isDialogOpen guard to prevent re-entrant ShowDialog calls
- Replace Hide() with WindowState.Minimized in OnClosing so the window
  goes to the dock and can be restored by clicking the dock icon
- Add ShowAndActivate() method with WindowState=Normal before Show()
  to properly restore window from minimized/hidden state
- Use ±1px min/max constraints instead of equal values to ensure macOS
  sets NSWindowStyleMaskMiniaturizable for the yellow traffic light
- Set ShutdownMode=OnExplicitShutdown so app stays alive when minimized
fix(macos): fix dialog re-opening loop, window lifecycle, minimize
Update build for win
- Remove all MinHeight/MaxHeight/MinWidth/MaxWidth constraints from
  MainWindow; keep only CanResize="True" so macOS enables all traffic
  light buttons (close, minimize, fullscreen) without restrictions
- Revert OnClosing back to Hide() instead of WindowState.Minimized
  (Minimized requires NSWindowStyleMaskMiniaturizable which was not
  set when equal min/max constraints were present, breaking both buttons)
- Revert TryStartHidden back to Hide()
- Set child windows (Server, Settings, About, Update, Policy) to
  CanResize="False" with no min/max constraints (modal dialogs don't
  need minimize support)
- Hero image and centered title/badges
- Download table with platform links
- Simplified feature list focused on end-user value
- Screenshots section with both app images
- Quick start guide (download, add server, connect)
- Collapsible build-from-source sections for Windows and macOS
- Architecture table reflecting both WPF and Avalonia GUI
- Troubleshooting table for common issues
- Removed developer-focused proxy fix changelog from top
## Summary
- fix the Windows TUN startup flow so the client no longer waits forever when the service fails to start or open its local port
- switch the client to the renamed `InvisibleGorilla-TUN` service while keeping backward compatibility with legacy `InvisibleMan-TUN` binaries
- update `build.ps1` so the client can build the local `../InvisibleGorilla-TUN` source first and only fall back to GitHub releases when needed
- refresh the README and release links to point to the `InvisibleGorilla` naming and repository layout

## Details
- add timeout-aware waiting in both scheduler implementations to prevent infinite polling during TUN startup
- update `TunnelProcess` to connect through `127.0.0.1` explicitly instead of relying on the first resolved host address
- detect the active TUN executable dynamically and support both old and new process names during startup and cleanup
- return explicit error states when the TUN service start or port activation times out
- extend the Windows build flow to use the local `InvisibleGorilla-TUN` repository when it is available nearby

## Test plan
- [x] run `.\build.ps1 -Step TUN` with a local `../InvisibleGorilla-TUN` repository and verify that the TUN service is built from source
- [x] run full `.\build.ps1` and verify that the client build completes successfully
- [x] confirm that the build no longer fails with `404` when a local TUN source checkout is present
- [ ] verify TUN mode manually in the Windows client UI after copying the built service into the app directory

## Notes
- existing NuGet warnings for `System.Windows.Forms` are still present and were not introduced by this change
- generated files under `InvisibleGorilla-XRay/TUN/` are build outputs and should be reviewed separately before committing
## Summary
- Split the Xray proxy port from the TUN control-service port so TUN mode no longer starts Xray on the wrong listener.
- Add end-to-end diagnostic logging around process launch, service connection, and tunnel enable/disable in both the app layer and shared core.
- Always copy the bundled `TUN` runtime files to build and publish outputs so the TUN service can start reliably after packaging.
## Why
TUN startup could fail or behave inconsistently because the client mixed the Xray listener port with the TUN service port, and failures were hard to diagnose in packaged builds. This change keeps each port dedicated to its own role and makes missing files or startup failures much easier to trace.
…ites

## Summary
- add an experimental `InvisibleGorilla-XRay.Android` Avalonia head and connect it to the shared `InvisibleGorilla.Core` flow
- make shared storage, settings, and diagnostic paths app-root aware so Android can use app-private storage instead of desktop-relative paths
- add `build-android.ps1` to auto-install missing prerequisites, prepare geo assets, build `libXRayCore.so`, and publish an APK
- update the README with Android build instructions, current limitations, and platform responsibilities
## Why
The repository already had Windows and macOS clients plus reusable shared core logic, but no Android packaging or mobile entry point. This change adds the Android groundwork without duplicating business logic and makes first-run APK builds much easier by installing missing dependencies automatically.
## Notes
- Android support is currently experimental.
- Android proxy mode currently runs a local Xray listener on `127.0.0.1:<port>`.
- Full `VpnService`-backed TUN routing still requires a follow-up mobile tunnel bridge runtime.
## Summary
- improve the Android server management flow with visible in-section status messages, config file import, deep-link intake, and selected-config actions for check/share/delete
- add Android intent handling for external `vless://`, `vmess://`, `trojan://`, `ss://`, and `invxray://` links so imports work from a cold start as well as from a running app
- add ABI-specific native runtime packaging and loading, plus `x86_64` Android build support, so the real proxy RUN flow works on the emulator instead of failing with a missing native runtime
## Summary
- redesign the Android server management flow to match the desktop app more closely, with dedicated configuration/subscription sections, icon-based actions, and localized import screens
- improve Android emulator/device behavior by fixing keyboard resize handling, deep-link config import, and x86_64 runtime packaging for real emulator validation
- replace text-heavy navigation/actions with desktop-style icons and add per-config status cards with check/share/delete actions
…fication

## Summary
- apply the Windows `Icon.ico` branding to the Android app icon by extracting the launcher asset and wiring it into the Android manifest for both normal and round icons
- align the Android header branding closer to the desktop version so the top title area matches the Windows/macOS look more closely
- add a live Android connection notification for proxy mode with localized status details, config name, protocol, proxy listener, traffic totals, transfer speed, and uptime
- request Android 13+ notification permission so ongoing connection notifications can be shown consistently on modern devices
hvkeyn and others added 29 commits March 28, 2026 02:29
## Summary
- apply the Windows `Icon.ico` branding to the Android launcher icon and round icon so the mobile app matches the desktop identity
- align the Android header visuals closer to the Windows/macOS version for a more consistent top-level branding presentation
- add an ongoing Android connection notification with localized status details, config name, protocol, proxy listener, traffic totals, transfer speed, and uptime
- rebuild fresh Android release APKs for both supported targets: `arm64-v8a` for physical devices and `x86_64` for the emulator
## Summary
- switch Android from the old proxy-only path to real device-wide routing through `VpnService` and the selected Xray config
- package the Android native runtime correctly for both `arm64-v8a` and `x86_64`, including the mobile `tun2socks` bridge
- fix VPN stop lifecycle so disconnect restores normal routing without hanging the app or triggering Android ANRs
- update Android status/notification flow to reflect the real VPN-backed connection state
## Why
Android builds could be installed, but device traffic was not actually routed through the selected config and stopping the VPN path could hang during teardown. This change makes browser/app traffic use the active config and stabilizes the start/stop lifecycle for mobile use.
…fications

## Summary
- fixed Android VPN start/stop lifecycle so `STOP` is safer, startup cleanup no longer emits a false `Stopped` notification, and the top Android notification now keeps detailed `Running` and `Stopped` state
- switched Android config checking to the shared native Xray test path instead of a raw socket probe, so the Wi-Fi/check action now validates the selected config correctly
- replaced direct full-config clipboard sharing with an in-app choice between copying the source link and exporting the full configuration, and persisted source links for imported configs
…p rules persistence

## Summary
- simplify Android connection notifications by removing `Endpoint` and `Protocol` from the expanded running/stopped notification content
- add shared cross-platform app rules persistence (`AppRule` / `AppRulesMode`) so Android, Windows, and macOS store the same bypass-selected-apps contract
- implement Android per-app bypass through `VpnService.Builder.AddDisallowedApplication(...)` and add installed-app discovery plus app-rules UI in Android settings
- extend the Windows TUN contract to pass excluded apps into `InvisibleGorilla-TUN` and stage accepted rules for diagnostics
- add desktop app discovery and app-rules editors to the Windows and macOS settings UIs
- add the macOS bridge/scaffold for a future native transparent-proxy helper based on the same excluded-app contract

## Known Issues
- Android `STOP` still reproduces a native crash on the emulator (`SIGABRT` in a `.NET TP Worker`) and needs a follow-up fix before the stop-path can be considered fully stable
- end-to-end runtime validation for Windows per-app bypass and the signed macOS native helper still needs to be completed on their target platforms
## Summary
- add shared cross-platform app bypass rules so selected apps can skip XRay on Android, Windows, and macOS
- wire Android bypass through `VpnService` disallowed applications, Windows through `-bypassApps` payloads passed to `InvisibleGorilla-TUN`, and macOS through a transparent-proxy bridge config plus helper scaffolding
- improve Android lifecycle stability and UX by cleaning notification noise, preserving connection details, and fixing the remaining `STOP` crash caused by the mobile bridge shutdown race

## Notes
- Windows command/staging runtime behavior is validated, but this pass intentionally avoided a fully invasive Wintun route-changing host test.
- macOS per-app enforcement is still scaffolded until the signed Network Extension is built and exercised on macOS.
…Windows, and macOS

## Summary
- add cross-platform app rules with three modes: `ALL_APPS`, `BYPASS_SELECTED_APPS`, and `ONLY_SELECTED_APPS`
- introduce shared app rule templates plus per-config template bindings in settings storage so each config can reuse a selected template
- replace heavy inline app lists with dedicated app-rules editors: Android overlay editor, Windows app-rules window, and macOS app-rules window
- wire the selected mode/template into each platform runtime: Android `VpnService` allow/disallow app handling, Windows mode-aware TUN payload/staging, and macOS bridge config generation
- sync localization/resources for the new app-rules UX and summaries across Android, Windows, and macOS
- fix the Windows server-config layout artifact where the app-rules summary block overlapped the tab header
- publish fresh Android Release APKs for both emulator (`android-x64`) and physical devices (`android-arm64`)
## Summary
- Fix the remaining Android app rules editor failure by replacing Avalonia-generated overlay field access in `MainView` with explicit control lookups, so `Manage` reliably opens the editor at runtime.
- Harden installed app discovery to skip and log problematic launcher packages instead of breaking the entire editor open path.
- Add localized load-failed messaging for the Android app rules flow and document the Android-specific control lookup caveat for future maintenance.
## Summary
- fix accidental app selection in the Android app picker by replacing the card tap behavior with a movement-aware press/release gesture
- ensure app rows toggle only on a real single tap and not while scrolling the list
- show installed application icons next to app names in the picker for faster visual recognition
…nfig imports

## Summary
- introduce session-scoped SOCKS credentials for TUN sessions and require password authentication on the local XRay SOCKS listener
- update Android and desktop TUN helper paths to use the authenticated local bridge, including Android auth-aware TCP and UDP tun2socks handlers
- sanitize imported raw JSON configs so runtime-managed `api`, `stats`, and `inbounds` sections are removed before storage
- keep desktop system-proxy mode on the temporary legacy path while applying the new secure listener contract to TUN flows
…build.sh

## Summary
Adds an `InvisibleGorilla-XRay.Linux` head targeting **ALT Linux + GNOME first**, distro-agnostic in practice (Debian/Ubuntu, Fedora/RHEL, openSUSE, Arch). The Linux GUI does **not** duplicate UI: it reuses the existing macOS Avalonia views (`MainWindow`, `ServerWindow`, `SettingsWindow`, `AppRulesWindow`, `AboutWindow`, `UpdateWindow`, `PolicyWindow`) and only contributes platform handlers, managers, factories, and the entry point. A single `./build.sh` is the only command an ALT Linux maintainer needs.
## What's new
- **`InvisibleGorilla-XRay.Linux` project** (`net7.0`, RIDs `linux-x64` and `linux-arm64`).
  - Avalonia bootstrap: `Program.cs`, `App.axaml(.cs)`.
  - Linked macOS XAML + code-behind exposed both via `<AvaloniaResource>` (runtime XAML loading) and via `<AdditionalFiles>` with `<SourceItemGroup>AvaloniaXaml</SourceItemGroup>` (so the Avalonia name source generator emits the strongly-typed `x:Name` field accessors that the linked code-behind partial classes depend on).
- **Linux platform integration**:
  - `LinuxAppManager`, `LinuxHandlersInitializer`, `LinuxPipeManager` — single-instance + deep-link IPC over a Unix domain socket.
  - `LinuxWindowFactory` — instantiates the linked macOS windows.
  - `LinuxLocalizationHandler` — `avares://InvisibleGorilla-XRay.Linux` resource resolver.
  - `LinuxNotifyHandler` — Avalonia `TrayIcon` (`StatusNotifierItem`/D-Bus) + `notify-send` toasts; both gracefully no-op when the binary or extension is missing.
  - `LinuxProxy` — GNOME proxy via `gsettings org.gnome.system.proxy*`; no-op on non-GNOME shells.
  - `LinuxStartup` — autostart through `~/.config/autostart/Invisible Gorilla XRay.desktop`.
  - `LinuxDeepLink` — `xdg-mime default` for `vless://`, `vmess://`, `ig-xray://`.
  - `LinuxTunnel` — `xjasonlyu/tun2socks` child process + `ip tuntap` / `ip route` / `resolvectl`; privileged steps via `pkexec` (preferred) or `sudo -n`; **fail-closed** on TUN failure.
  - `LinuxAppRulesBridge` — persists the selected app-rules contract as a JSON manifest for a future kernel-side helper (cgroups + `iptables -m owner`); enforcement intentionally deferred.
  - `MacInstalledAppDiscovery` — parses XDG `.desktop` files plus Flatpak/Snap dirs. Implemented inside the Linux project but kept under the `InvisibleGorillaXRay.Mac.Services` namespace so the linked App Rules UI binds to it with zero view-side changes.
- **`build.sh`** at the repo root:
  - Detects ALT (apt-rpm), Debian/Ubuntu (apt), Fedora/RHEL (dnf), openSUSE (zypper), Arch (pacman); asks once for sudo before installing deps.
  - Installs build tools, Avalonia runtime libs, .NET SDK 7 (via Microsoft script when distro doesn't ship it), Go, and runtime helpers (`libnotify`, `policykit-1`, `iproute2`).
  - Builds `libXRayCore.so`, downloads matching `tun2socks-linux-<arch>` and `geoip.dat` / `geosite.dat`.
  - `dotnet publish -c Release -r linux-{x64|arm64} --self-contained -p:PublishSingleFile=true` into `publish-linux/<rid>/`.
  - Bundles the result into `dist-linux/<rid>/` with an `install.sh` that drops the `.desktop` file into `~/.local/share/applications/` and links the binary into `~/.local/bin/`.
- **Solution + ignore**: `InvisibleGorilla-XRay.sln` registers the new project; `.gitignore` excludes `publish-linux/`, `dist-linux/`, and the project's `bin/`, `obj/`, `TUN/` outputs.
- **Memory bank + `.cursorrules`** updated with Linux-specific stack, patterns, validation snapshot, risks, artifacts, and rules (notably the `<AdditionalFiles SourceItemGroup="AvaloniaXaml">` requirement).
## Why this shape
Linking the macOS XAML instead of forking it keeps the Linux head additive and prevents UI drift. It also surfaces a non-obvious Avalonia constraint: `<AvaloniaResource>` alone does **not** trigger the name source generator for linked files — the missing `<SourceItemGroup>AvaloniaXaml</SourceItemGroup>` metadata caused 227 × `CS0103` errors before the fix.
## Validation
- `dotnet build InvisibleGorilla-XRay.Linux/InvisibleGorilla-XRay.Linux.csproj -c Release` → 0 errors on Windows.
- `dotnet build InvisibleGorilla-XRay.sln -c Release` → builds Core, Mac, Android, and Linux cleanly. The only remaining error is `MSB3027` on `Invisible Gorilla XRay.exe` due to a locally running WPF instance locking the file; it is unrelated to the Linux head and goes away once that instance is closed.
- Real ALT Linux + GNOME runtime validation (TUN, gsettings proxy, tray, notifications, autostart, deep links) is the next step and was deliberately scoped out of this build-side port.
- Read pinned .NET SDK from global.json; install fallback to .dotnet-sdk
- Isolate DOTNET_CLI_HOME and NUGET_PACKAGES under repo
- Output to publish-macos/<rid>/ and dist-macos/<rid>/ with run-igxray and README
- Fail bundle if dylib/geo missing; trap ERR for actionable messages
- Document paths in README; ignore publish-macos and dist-macos
Store macOS settings, configs, and logs in user-writable Application Support while keeping runtime assets in the app bundle. This prevents root-owned build outputs from crashing on first launch and adds startup crash diagnostics.
Add log rotation, share/save/clear UI, global exception handlers, and
defensive ONLY_SELECTED_APPS checks to prevent black-screen freezes when
the whitelist resolves to zero apps.
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