Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
7368240
Merge pull request #1213 from ionite34/pr-linux-single-instance
mohnjiles Mar 31, 2026
58604fb
Merge pull request #1217 from ionite34/app-notifications
ionite34 Apr 4, 2026
4991c8b
Update CHANGELOG for version 2.15.7
ionite34 Apr 4, 2026
8ee123a
Fix backport conflict
ionite34 Apr 4, 2026
310abee
Merge pull request #1218 from ionite34/backport/main/pr-1217
ionite34 Apr 4, 2026
ee3b396
Merge branch 'main' into backport/main/pr-1213
ionite34 Apr 5, 2026
d37936b
Merge pull request #1216 from ionite34/backport/main/pr-1213
ionite34 Apr 5, 2026
363135e
Merge pull request #1219 from ionite34/download-fixes-and-onedrive-wa…
mohnjiles Apr 8, 2026
96cfc53
Merge pull request #1221 from ionite34/backport/main/pr-1219
mohnjiles Apr 8, 2026
5fbbb93
Merge branch 'main' of https://github.com/LykosAI/StabilityMatrix-Dev…
mohnjiles Apr 8, 2026
2ed82eb
Update CHANGELOG with changes from contributors
mohnjiles Apr 8, 2026
913ebf9
Merge pull request #1222 from ionite34/downmerg-stuff
mohnjiles Apr 8, 2026
d1ff724
Merge pull request #1224 from ionite34/fix-add-package-tip-showing-in…
mohnjiles Apr 10, 2026
15df0fd
update chagenlog
mohnjiles Apr 10, 2026
e331c8a
Fix merge conflicts
mohnjiles Apr 10, 2026
b2d3439
copypasta
mohnjiles Apr 10, 2026
4105c6c
Merge pull request #1226 from ionite34/fix-setuptools-error-reforge
mohnjiles Apr 10, 2026
9390f62
Fix merge conflict
mohnjiles Apr 10, 2026
8fcd27f
fix chagenlog
mohnjiles Apr 10, 2026
5aa4780
Merge pull request #1225 from ionite34/backport/main/pr-1224
mohnjiles Apr 10, 2026
582f43d
Merge branch 'main' into backport/main/pr-1226
mohnjiles Apr 10, 2026
63e89d0
Merge branch 'main' of https://github.com/LykosAI/StabilityMatrix-Dev…
mohnjiles Apr 10, 2026
aab84b1
Merge pull request #1227 from ionite34/backport/main/pr-1226
mohnjiles Apr 10, 2026
0fd8456
Merge branch 'main' into downmerg-again
mohnjiles Apr 10, 2026
b5c4bb9
Merge pull request #1228 from ionite34/downmerg-again
mohnjiles Apr 10, 2026
877aab5
Merge pull request #1230 from ionite34/shoutout-chagenlog
mohnjiles Apr 10, 2026
3cfd567
fix chagenlog
mohnjiles Apr 10, 2026
2511c75
Merge pull request #1231 from ionite34/backport/main/pr-1230
mohnjiles Apr 10, 2026
d63522f
Merge pull request #1232 from ionite34/patreon-migration-and-accounts
ionite34 Apr 11, 2026
80a7ca9
Revise CHANGELOG for recent updates and fixes
ionite34 Apr 11, 2026
eaecd3a
Fix conflict
ionite34 Apr 11, 2026
b8dcf3c
Fix more conflict
ionite34 Apr 11, 2026
9353aa1
Fix closing tag for UserControlBase in AccountSettingsPage
ionite34 Apr 11, 2026
f7b0bbc
Adjust grid rows for account settings expanders
ionite34 Apr 11, 2026
8afacf5
Remove extra file
ionite34 Apr 11, 2026
d688dfb
Remove Gemini API section
ionite34 Apr 11, 2026
5a6aa69
Merge pull request #1233 from ionite34/backport/main/pr-1232
ionite34 Apr 11, 2026
49a073c
Revise supporter acknowledgments in CHANGELOG.md
ionite34 Apr 11, 2026
b7d3a1d
Update CHANGELOG.md
ionite34 Apr 11, 2026
891cc67
Merge pull request #1235 from ionite34/ionite34-patch-1
ionite34 Apr 11, 2026
fe1b275
Merge pull request #1237 from ionite34/member-and-localize
ionite34 Apr 12, 2026
730d1c2
Merge pull request #1238 from ionite34/backport/main/pr-1237
ionite34 Apr 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,45 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning 2.0](https://semver.org/spec/v2.0.0.html).

## v2.15.7
### Added
- Added single-instance window activation signaling so reopening the app restores and focuses the existing desktop window instead of launching a duplicate instance
- Added notification system with localizable banner and markdown detail dialog UI
- Added warning in data directory selector when an OneDrive folder is selected
- Added support in the Checkpoints page to distinguish standard updates from Early Access-only updates - thanks to @x0x0b!
- Added torch index for Strix/Gorgon Point Ryzen AI APUs on Windows - thanks to @NeuralFault!
- Added retry button to failed downloads - thanks to @NeuralFault!
- Added new Membership support in Account Settings with Patreon migration prompt
### Changed
- Settings file saves are now atomic to prevent corruption from interrupted writes
### Fixed
- Updated torch indexes for A1111, ComfyUI, InvokeAI, and Forge-based UIs to rocm7.2 / cu128 depending on GPU - thanks to @NeuralFault!
- Replaced the "Become a Patron" footer button with "Support Us", linking to the new direct Lykos support page at lykos.ai/membership
- Updated the prompt dialog shown when enabling features like Accelerated Model Discovery to use Lykos accounts instead of Patreon linking
- Moved the Patreon connection in Account Settings to a new "Legacy Connections" section, only shown for users with an existing Patreon link
- Localized previously hardcoded strings on the Account Settings page (menu items, descriptions, section headers) and added Japanese, Korean, German, and French translations
### Fixed
- Fixed an issue where `Align Your Steps` scheduler and Unet Loader workflows ignored Regional Prompting (and other addon) conditioning modifiers.
- Fixed the Package Manager "Add Package" teaching tip opening inopportunely while packages were still loading or after opening the add-package dialog
- Fixed bold text not rendering in markdown dialogs on Windows 11 due to Avalonia 11.3.x variable font regression with Segoe UI Variable Text
- Fixed Japanese text appearing compressed/squished in markdown dialogs by ensuring the bundled NotoSansJP font is used for CTextBlock rendering
- Fixed ContentDialog title and buttons not using the correct font for Japanese locale (NotoSansJP) when shown as overlay
- Added missing `CBold` and `CItalic` inline styles to the markdown style sheet
- Fixed downloads failing with "The request message was already sent" when the server doesn't return Content-Length on the first attempt, caused by reusing a consumed HttpRequestMessage in the retry loop
- Fixed downloads from sources that redirect to CivitAI/HuggingFace (e.g. CivArchive) failing with Unauthorized by resolving the redirect target URL and applying auth headers for the correct domain
- Fixed dropdown menu overlayed in Inference UI Model Cards not being scrollable on Linux - thanks to @NeuralFault!
- Fixed model downloads failing on VPN connections - thanks to @NeuralFault!
- Fixed [#1598](https://github.com/LykosAI/StabilityMatrix/issues/1598) - download progress bar showing 100% immediately for fresh downloads due to missing Content-Length fallback when Content-Range header is absent
- Fixed [#1597](https://github.com/LykosAI/StabilityMatrix/issues/1597) - reForge launch failing due to setuptools version
- Fixed [#1596](https://github.com/LykosAI/StabilityMatrix/issues/1596) - package installs and managed embedded Python startup being poisoned by inherited shell Python activation variables such as `PYTHONHOME`, `PYTHONPATH`, `VIRTUAL_ENV`, and Conda environment variables
- Fixed [#1590](https://github.com/LykosAI/StabilityMatrix/issues/1590) - Startup crash when settings file is corrupted. Settings files are now self-healing with automatic recovery from null bytes, truncated JSON, and missing brackets
- Potentially fixed [#1578](https://github.com/LykosAI/StabilityMatrix/issues/1578) - `SocketException: Address already in use` on Linux startup by cleaning stale interprocess socket files and reactivating the existing window
- Fixed [#1397](https://github.com/LykosAI/StabilityMatrix/issues/1397), [#610](https://github.com/LykosAI/StabilityMatrix/issues/610) - duplicate pip package entries in results - thanks to @e-nord!
### Supporters
#### 🌟 Visionaries
Lifting up our legendary Visionaries: **Waterclouds**, **JungleDragon**, **bluepopsicle**, **Bob S**, and **whudunit**. Through every release, every milestone, and every twist of this wild journey, your support has been our north star. A huge welcome to our newest Visionaries **Droolguy** and **snotty** (leveling up from the Pioneer crew!), a warm welcome back to longtime Visionary **Ibixat**, and an equally huge welcome to **LG** and **MrMxyzptlk12836**, making their Stability Matrix debut straight at the Visionary tier - so glad to have you all on board! We cannot thank you enough for standing behind Stability Matrix!
#### 🚀 Pioneers
And to our mighty Pioneer crew - the folks who keep the engine humming - thank you for everything! Massive shoutout to: **Szir777**, **Noah M**, **[USA]TechDude**, **Thom**, **SeraphOfSalem**, **Desert Viber**, **Adam**, **ACTUALLY_the_Real_Willem_Dafoe**, **takyamtom**, **robek**, **Ghislain G**, **Phil R**, **Tundra Everquill**, **Andrew B**, **SinthCore**, and **Ahmed S**. And a very warm welcome to our newest Pioneers **Commissar Lord Death**, **Firelight**, and **jweg**, plus a heartfelt shoutout to one more new Pioneer who joined us quietly through the Stripe migration - you know who you are, and we're so glad to have you!

And one more heartfelt thank you to everyone now supporting us directly through our new platform - this next chapter wouldn't be possible without your trust, and we're so grateful you've come along for the ride!

## v2.15.6
### Added
Expand Down
53 changes: 52 additions & 1 deletion StabilityMatrix.Avalonia/App.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -376,11 +376,13 @@ internal static void ConfigurePageViewModels(IServiceCollection services)
provider.GetRequiredService<IModelIndexService>(),
provider.GetRequiredService<Lazy<IModelDownloadLinkHandler>>(),
provider.GetRequiredService<INotificationService>(),
provider.GetRequiredService<IAppNotificationService>(),
provider.GetRequiredService<IAnalyticsHelper>(),
provider.GetRequiredService<IUpdateHelper>(),
provider.GetRequiredService<ISecretsManager>(),
provider.GetRequiredService<INavigationService<MainWindowViewModel>>(),
provider.GetRequiredService<INavigationService<SettingsViewModel>>()
provider.GetRequiredService<INavigationService<SettingsViewModel>>(),
provider.GetRequiredService<IDistributedSubscriber<string, Uri>>()
)
{
Pages =
Expand Down Expand Up @@ -451,6 +453,14 @@ internal static IServiceCollection ConfigureServices(bool disableMessagePipeInte
// Named pipe interprocess communication on Windows and Linux for uri handling
if (!disableMessagePipeInterprocess && (Compat.IsWindows || Compat.IsLinux))
{
// On Linux, named pipes use Unix domain sockets which leave stale socket files
// if the app crashes or exits without cleanup. Delete the stale file if no other
// instance is running, so the new instance can bind successfully.
if (Compat.IsLinux)
{
CleanupStaleUnixSocket("StabilityMatrix");
}

services.AddMessagePipe().AddNamedPipeInterprocess("StabilityMatrix");
}
else
Expand Down Expand Up @@ -973,6 +983,47 @@ private void OnExit(object? sender, EventArgs _)
}
}

/// <summary>
/// On Linux, .NET named pipes use Unix domain sockets. If the app exits without cleanup,
/// the socket file remains and prevents the next instance from binding.
/// This deletes the stale socket file if no other instance holds it.
/// </summary>
private static void CleanupStaleUnixSocket(string pipeName)
{
try
{
var tempPath = Path.GetTempPath();
var socketPath = Path.Combine(tempPath, $"CoreFxPipe_{pipeName}");

if (!File.Exists(socketPath))
return;

// Try connecting to see if another instance is actually listening
using var socket = new System.Net.Sockets.Socket(
System.Net.Sockets.AddressFamily.Unix,
System.Net.Sockets.SocketType.Stream,
System.Net.Sockets.ProtocolType.Unspecified
);

try
{
socket.Connect(new System.Net.Sockets.UnixDomainSocketEndPoint(socketPath));
// Connected successfully - another instance is running, don't delete
}
catch (System.Net.Sockets.SocketException ex)
when (ex.SocketErrorCode == System.Net.Sockets.SocketError.ConnectionRefused)
{
// A refused connection means the socket file exists but nothing is listening anymore.
File.Delete(socketPath);
Logger.Info("Deleted stale Unix domain socket: {SocketPath}", socketPath);
}
}
catch (Exception e)
{
Logger.Warn(e, "Failed to clean up stale Unix domain socket");
}
}

private static void OnServiceProviderDisposing(ServiceProvider serviceProvider)
{
// Force materialize SharedFolders so its DisposeAsync is called
Expand Down
4 changes: 4 additions & 0 deletions StabilityMatrix.Avalonia/Assets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ internal static class Assets

public static Uri PatreonUrl { get; } = new("https://patreon.com/StabilityMatrix");

public static Uri MembershipUrl { get; } = new("https://lykos.ai/membership?ref=a1");

public static Uri PatreonBlogPostUrl { get; } = new("https://lykos.ai/blog/patreon-update");

public static Uri CivitAIUrl { get; } = new("https://civitai.com");

public static Uri LykosForgotPasswordUrl { get; } = new("https://lykos.ai/forgot-password");
Expand Down
8 changes: 8 additions & 0 deletions StabilityMatrix.Avalonia/Controls/BetterContentDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,14 @@ public bool CloseOnClickOutside

public BetterContentDialog()
{
// Ensure the dialog uses the correct platform font (e.g. NotoSansJP for Japanese).
// ContentDialog is shown as an overlay and its template elements (title, buttons)
// don't inherit ContentControlThemeFontFamily from the app resources.
if (App.Current is { } app)
{
FontFamily = app.GetPlatformDefaultFontFamily();
}

AddHandler(LoadedEvent, OnLoaded);
}

Expand Down
33 changes: 33 additions & 0 deletions StabilityMatrix.Avalonia/Controls/NotificationBanner.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<UserControl
x:Class="StabilityMatrix.Avalonia.Controls.NotificationBanner"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:designData="clr-namespace:StabilityMatrix.Avalonia.DesignData"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:ui="using:FluentAvalonia.UI.Controls"
xmlns:vm="using:StabilityMatrix.Avalonia.ViewModels"
d:DataContext="{x:Static designData:DesignData.NotificationBannerViewModel}"
d:DesignHeight="150"
d:DesignWidth="1100"
x:DataType="vm:NotificationBannerViewModel"
IsVisible="{Binding IsVisible}"
mc:Ignorable="d">

<ui:InfoBar
Margin="12,8,12,4"
CloseButtonCommand="{Binding DismissClickedCommand}"
FontSize="14"
FontWeight="SemiBold"
IsClosable="{Binding IsDismissible}"
IsOpen="True"
Message="{Binding Message}"
Severity="{Binding Severity}">
<ui:InfoBar.ActionButton>
<Button
Command="{Binding ActionClickedCommand}"
Content="{Binding ActionLabel}"
IsVisible="{Binding HasAction}" />
</ui:InfoBar.ActionButton>
</ui:InfoBar>
</UserControl>
13 changes: 13 additions & 0 deletions StabilityMatrix.Avalonia/Controls/NotificationBanner.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Avalonia.Controls;
using Injectio.Attributes;

namespace StabilityMatrix.Avalonia.Controls;

[RegisterTransient<NotificationBanner>]
public partial class NotificationBanner : UserControlBase
{
public NotificationBanner()
{
InitializeComponent();
}
}
23 changes: 22 additions & 1 deletion StabilityMatrix.Avalonia/DesignData/DesignData.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
Expand Down Expand Up @@ -475,6 +475,27 @@ public static void Initialize()
public static FirstLaunchSetupViewModel FirstLaunchSetupViewModel =>
Services.GetRequiredService<FirstLaunchSetupViewModel>();

public static NotificationBannerViewModel NotificationBannerViewModel =>
DialogFactory.Get<NotificationBannerViewModel>(vm =>
{
vm.Show(
new Core.Models.Notifications.AppNotification
{
Id = "test",
Type = Core.Models.Notifications.AppNotificationType.Banner,
Priority = Core.Models.Notifications.AppNotificationPriority.Normal,
Message = new Dictionary<string, string> { { "en", "This is a test notification." } },
Style = new Core.Models.Notifications.AppNotificationStyle { Variant = "info" },
Action = new Core.Models.Notifications.AppNotificationAction
{
Type = Core.Models.Notifications.AppNotificationActionType.Url,
Label = new Dictionary<string, string> { { "en", "Learn More" } },
Url = "https://example.com",
},
}
);
});

public static LaunchPageViewModel LaunchPageViewModel =>
Services.GetRequiredService<LaunchPageViewModel>();

Expand Down
Loading
Loading