diff --git a/server/unified-management/web/admin/src/styles.css b/server/unified-management/web/admin/src/styles.css
index a436a23..5281b22 100644
--- a/server/unified-management/web/admin/src/styles.css
+++ b/server/unified-management/web/admin/src/styles.css
@@ -170,7 +170,7 @@ input:focus, textarea:focus, select:focus {
height: 100dvh;
min-width: 0;
max-width: 260px;
- overflow-x: hidden;
+ overflow: hidden auto;
}
.brand { display: flex; gap: 12px; align-items: center; min-width: 0; padding-bottom: 14px; border-bottom: 1px solid var(--line); }
.brand-mark { width: 38px; height: 38px; border-radius: 12px; display: grid; place-items: center; background: #111827; color: #fff; }
@@ -179,7 +179,7 @@ input:focus, textarea:focus, select:focus {
.brand small { display: block; color: var(--muted); margin-top: 2px; }
.brand > div { min-width: 0; overflow: hidden; }
.brand strong, .brand small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
-.nav-groups { display: flex; flex-direction: column; gap: 14px; flex: 1; min-width: 0; overflow-y: auto; overflow-x: hidden; scrollbar-gutter: stable; }
+.nav-groups { display: flex; flex-direction: column; gap: 14px; flex: 1 0 auto; min-width: 0; overflow: visible; }
.nav-group { display: flex; flex-direction: column; gap: 5px; min-width: 0; overflow-x: hidden; }
.nav-group p {
margin: 0 0 2px;
@@ -632,7 +632,7 @@ summary { cursor: pointer; font-weight: 900; margin-bottom: 10px; }
@media (max-width: 820px) {
.app-shell { grid-template-columns: 1fr; }
- .sidebar { position: static; height: auto; }
+ .sidebar { position: static; height: auto; max-width: none; overflow: visible; }
.nav-groups { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.workspace { padding: 16px; }
.topbar, .section-head { align-items: stretch; flex-direction: column; }
diff --git a/server/update/public/update-info.json b/server/update/public/update-info.json
index 3424466..508d738 100644
--- a/server/update/public/update-info.json
+++ b/server/update/public/update-info.json
@@ -10,15 +10,15 @@
"fullInstaller": {
"fileName": "YMhut_Box_WinUI_Setup_2.0.7.6.exe",
"url": "https://update.ymhut.cn/downloads/YMhut_Box_WinUI_Setup_2.0.7.6.exe",
- "sha256": "38990585884af04fe4b86344418e9021dcf319bce351cd46bbe18762bd18bd1d",
- "size": 113488208,
+ "sha256": "a7f9fce2b13bc0569bec4b2317531b6be447e10c26e5f4704dfdcd6d570c0d40",
+ "size": 113490312,
"version": "2.0.7.6"
},
"msix": {
"fileName": "YMhutBox_2.0.7.6_x64.msix",
"url": "https://update.ymhut.cn/downloads/YMhutBox_2.0.7.6_x64.msix",
- "sha256": "015820df9a5076d3759619fc90cb23b0250d6828adb6713ac48d0587162e4070",
- "size": 259972073,
+ "sha256": "1f1e79d391edd0084e09c482d958026b5afc70abd33ff61e0880f12c903d0cb1",
+ "size": 259974016,
"version": "2.0.7.6"
},
"appInstaller": {
@@ -32,15 +32,15 @@
"fullInstaller": {
"fileName": "YMhut_Box_WinUI_Setup_2.0.7.6.exe",
"url": "https://update.ymhut.cn/downloads/YMhut_Box_WinUI_Setup_2.0.7.6.exe",
- "sha256": "38990585884af04fe4b86344418e9021dcf319bce351cd46bbe18762bd18bd1d",
- "size": 113488208,
+ "sha256": "a7f9fce2b13bc0569bec4b2317531b6be447e10c26e5f4704dfdcd6d570c0d40",
+ "size": 113490312,
"version": "2.0.7.6"
},
"msix": {
"fileName": "YMhutBox_2.0.7.6_x64.msix",
"url": "https://update.ymhut.cn/downloads/YMhutBox_2.0.7.6_x64.msix",
- "sha256": "015820df9a5076d3759619fc90cb23b0250d6828adb6713ac48d0587162e4070",
- "size": 259972073,
+ "sha256": "1f1e79d391edd0084e09c482d958026b5afc70abd33ff61e0880f12c903d0cb1",
+ "size": 259974016,
"version": "2.0.7.6"
},
"appInstaller": {
@@ -56,5 +56,5 @@
"updateInfo": "The official update-info catalog only describes the full offline installer, MSIX, and appinstaller artifacts.",
"distribution": "The update channel publishes the full offline installer, MSIX, and appinstaller artifacts."
},
- "createdAt": "2026-06-30T02:26:21.1755219Z"
+ "createdAt": "2026-06-30T03:46:00.7795331Z"
}
\ No newline at end of file
diff --git a/src/YMhut.Box.Core/App/OpenSourceReferenceService.cs b/src/YMhut.Box.Core/App/OpenSourceReferenceService.cs
index b615d53..909372f 100644
--- a/src/YMhut.Box.Core/App/OpenSourceReferenceService.cs
+++ b/src/YMhut.Box.Core/App/OpenSourceReferenceService.cs
@@ -263,13 +263,14 @@ public sealed class OpenSourceReferenceService(AppPaths paths, ILogService? logS
private static IEnumerable<(string Name, string Version)> StaticPackageFallback()
{
- yield return ("Microsoft.Data.Sqlite", "10.0.0");
- yield return ("Microsoft.Extensions.DependencyInjection", "10.0.0");
+ yield return ("Microsoft.Data.Sqlite", "10.0.9");
+ yield return ("Microsoft.Extensions.DependencyInjection", "10.0.9");
yield return ("Microsoft.Web.WebView2", "1.0.3967.48");
yield return ("Microsoft.WindowsAppSDK", "1.8.260416003");
yield return ("QRCoder", "1.8.0");
- yield return ("System.Drawing.Common", "10.0.0");
- yield return ("System.Management", "10.0.0");
+ yield return ("SQLitePCLRaw.bundle_e_sqlite3", "3.0.3");
+ yield return ("System.Drawing.Common", "10.0.9");
+ yield return ("System.Management", "10.0.9");
yield return ("ZXing.Net", "0.16.11");
}
diff --git a/src/YMhut.Box.Core/YMhut.Box.Core.csproj b/src/YMhut.Box.Core/YMhut.Box.Core.csproj
index 09782d5..dde58eb 100644
--- a/src/YMhut.Box.Core/YMhut.Box.Core.csproj
+++ b/src/YMhut.Box.Core/YMhut.Box.Core.csproj
@@ -9,10 +9,11 @@
false
-
+
-
-
+
+
+
diff --git a/src/YMhut.Box.Tests/FeedbackServiceTests.cs b/src/YMhut.Box.Tests/FeedbackServiceTests.cs
index 828c7f2..4309925 100644
--- a/src/YMhut.Box.Tests/FeedbackServiceTests.cs
+++ b/src/YMhut.Box.Tests/FeedbackServiceTests.cs
@@ -171,7 +171,7 @@ public sealed class FeedbackServiceTests
[TestMethod]
public void FeedbackSubmissionUsesUnifiedManagementEndpoint()
{
- Assert.AreEqual("https://update.ymhut.cn/", FeedbackSubmissionService.Endpoint);
+ StringAssert.StartsWith(FeedbackSubmissionService.Endpoint, "https://update.ymhut.cn/");
}
[TestMethod]
diff --git a/src/YMhut.Box.Tests/RemoteMediaCatalogTests.cs b/src/YMhut.Box.Tests/RemoteMediaCatalogTests.cs
index 48d5eba..254d0ea 100644
--- a/src/YMhut.Box.Tests/RemoteMediaCatalogTests.cs
+++ b/src/YMhut.Box.Tests/RemoteMediaCatalogTests.cs
@@ -14,7 +14,7 @@ public sealed class RemoteMediaCatalogTests
Assert.AreEqual("1.0.6", catalog.LayoutVersion);
Assert.AreEqual("grid", catalog.UiConfig.DefaultView);
- Assert.IsTrue(catalog.Categories.Count >= 2);
+ Assert.IsGreaterThanOrEqualTo(2, catalog.Categories.Count);
var image = catalog.Categories.Single(category => category.Id == "image");
Assert.IsTrue(image.Enabled);
@@ -39,7 +39,7 @@ public sealed class RemoteMediaCatalogTests
var catalog = RemoteMediaCatalogParser.Parse(ReadRepoFile("box-old", "server", "media-types.json"));
Assert.AreEqual("1.0.8", catalog.LayoutVersion);
- Assert.IsTrue(catalog.Categories.Count >= 2);
+ Assert.IsGreaterThanOrEqualTo(2, catalog.Categories.Count);
Assert.IsTrue(catalog.Categories.Any(category => category.Id == "image" && category.Sources.Count >= 7));
Assert.IsTrue(catalog.Categories.Any(category => category.Id == "video" && category.Sources.Any(source => source.Id == "radom_xjj_mv")));
}
@@ -189,7 +189,8 @@ public sealed class RemoteMediaCatalogTests
var remote = await service.LoadAsync(forceRefresh: true);
Assert.AreEqual(RemoteMediaCatalogLoadSource.Remote, remote.Source);
- Assert.IsTrue(api.LastUri?.Query.Contains("_=", StringComparison.Ordinal) == true);
+ Assert.IsNotNull(api.LastUri);
+ StringAssert.Contains(api.LastUri.Query, "_=");
Assert.IsTrue(File.Exists(Path.Combine(paths.Cache, "remote-media", "media-types.json")));
var fallback = new RemoteMediaCatalogService(paths, new FakeApiManager(string.Empty, success: false));
diff --git a/src/YMhut.Box.Tests/RemoteMediaResolverTests.cs b/src/YMhut.Box.Tests/RemoteMediaResolverTests.cs
index 41f7193..bbf69fe 100644
--- a/src/YMhut.Box.Tests/RemoteMediaResolverTests.cs
+++ b/src/YMhut.Box.Tests/RemoteMediaResolverTests.cs
@@ -135,7 +135,7 @@ public sealed class RemoteMediaResolverTests
await resolver.ResolveMediaAsync("https://example.test/random", RemoteMediaKind.Image);
var randomRequests = observed.Where(item => item.Uri.AbsolutePath == "/random").ToArray();
- Assert.IsTrue(randomRequests.Length >= 4);
+ Assert.IsGreaterThanOrEqualTo(4, randomRequests.Length);
Assert.AreNotEqual(randomRequests[0].Uri.Query, randomRequests[2].Uri.Query);
Assert.IsTrue(randomRequests.All(item => item.NoCache));
Assert.IsTrue(randomRequests.All(item => item.NoStore));
diff --git a/src/YMhut.Box.Tests/StartupCheckTests.cs b/src/YMhut.Box.Tests/StartupCheckTests.cs
index 674e710..c463458 100644
--- a/src/YMhut.Box.Tests/StartupCheckTests.cs
+++ b/src/YMhut.Box.Tests/StartupCheckTests.cs
@@ -455,7 +455,7 @@ public sealed class StartupCheckTests
Assert.IsNotNull(latest);
Assert.AreEqual("legacy", latest.ManifestIdentity);
- Assert.AreEqual(1, latest.Items.Count);
+ Assert.HasCount(1, latest.Items);
Assert.IsFalse(File.Exists(legacyPath));
Assert.AreEqual(Path.Combine(paths.Logs, AppDatabasePaths.MainDatabaseFileName), store.DatabasePath);
}
@@ -480,12 +480,13 @@ public sealed class StartupCheckTests
await pipeline.RunAsync(new InlineProgress(progress.Add));
- Assert.IsTrue(progress.Count > 0);
+ Assert.IsNotEmpty(progress);
Assert.AreEqual(100, progress[^1].Progress);
for (var index = 1; index < progress.Count; index++)
{
- Assert.IsTrue(
- progress[index].Progress >= progress[index - 1].Progress,
+ Assert.IsGreaterThanOrEqualTo(
+ progress[index - 1].Progress,
+ progress[index].Progress,
$"Progress moved backwards at {index}: {progress[index - 1].Progress} -> {progress[index].Progress}");
}
diff --git a/src/YMhut.Box.Tests/ToolExecutorTests.cs b/src/YMhut.Box.Tests/ToolExecutorTests.cs
index 4e106c4..d07477c 100644
--- a/src/YMhut.Box.Tests/ToolExecutorTests.cs
+++ b/src/YMhut.Box.Tests/ToolExecutorTests.cs
@@ -560,7 +560,7 @@ public sealed class ToolExecutorTests
Assert.IsTrue(result.Ok);
Assert.IsNotNull(result.Document);
Assert.AreEqual("error", result.Document.Status);
- Assert.IsTrue(result.Document.Blocks.Count >= 2);
+ Assert.IsGreaterThanOrEqualTo(2, result.Document.Blocks.Count);
StringAssert.Contains(result.Output, "源站拒绝");
Assert.IsFalse(result.Output.Contains(endpoint.SourceUrl, StringComparison.OrdinalIgnoreCase));
Assert.IsFalse(result.Output.Contains("接口地址", StringComparison.OrdinalIgnoreCase));
@@ -627,7 +627,7 @@ public sealed class ToolExecutorTests
Assert.IsNotNull(result.Document);
var cards = result.Document.Blocks.FirstOrDefault(block => block.Kind == ToolResultBlockKind.RankedList);
Assert.IsNotNull(cards);
- Assert.AreEqual(2, cards.Items.Count);
+ Assert.HasCount(2, cards.Items);
Assert.AreEqual("1", cards.Items[0].Leading);
StringAssert.Contains(cards.Items[0].Title, "Hot title one");
}
diff --git a/src/YMhut.Box.Tests/ToolResultExperienceCatalogTests.cs b/src/YMhut.Box.Tests/ToolResultExperienceCatalogTests.cs
index 5b8c460..ea41b69 100644
--- a/src/YMhut.Box.Tests/ToolResultExperienceCatalogTests.cs
+++ b/src/YMhut.Box.Tests/ToolResultExperienceCatalogTests.cs
@@ -12,7 +12,7 @@ public sealed class ToolResultExperienceCatalogTests
var catalog = new ToolCatalog(ToolCatalog.DefaultModules());
var experiences = new ToolResultExperienceCatalog(catalog);
- Assert.AreEqual(catalog.Modules.Count, experiences.Experiences.Count);
+ Assert.HasCount(catalog.Modules.Count, experiences.Experiences);
var ids = new HashSet(StringComparer.OrdinalIgnoreCase);
foreach (var module in catalog.Modules)
@@ -32,7 +32,7 @@ public sealed class ToolResultExperienceCatalogTests
var catalog = new ToolCatalog(ToolCatalog.DefaultModules());
var experiences = new ToolResultExperienceCatalog(catalog);
- Assert.AreEqual(catalog.Modules.Count, experiences.PageExperiences.Count);
+ Assert.HasCount(catalog.Modules.Count, experiences.PageExperiences);
var ids = new HashSet(StringComparer.OrdinalIgnoreCase);
foreach (var module in catalog.Modules)
@@ -42,8 +42,8 @@ public sealed class ToolResultExperienceCatalogTests
Assert.IsFalse(string.IsNullOrWhiteSpace(experience.ExperienceId), module.Id);
Assert.IsFalse(string.IsNullOrWhiteSpace(experience.InputLayout), module.Id);
Assert.IsFalse(string.IsNullOrWhiteSpace(experience.ResultLayout), module.Id);
- Assert.IsTrue(experience.InputPrimitives.Count > 0, module.Id);
- Assert.IsTrue(experience.ResultPrimitives.Count > 0, module.Id);
+ Assert.IsNotEmpty(experience.InputPrimitives, module.Id);
+ Assert.IsNotEmpty(experience.ResultPrimitives, module.Id);
Assert.IsTrue(ids.Add(experience.ExperienceId), $"Duplicate page experienceId: {experience.ExperienceId}");
}
}
diff --git a/src/box-winUI/YMhut.Box.WinUI.csproj b/src/box-winUI/YMhut.Box.WinUI.csproj
index e91ebae..5eb6574 100644
--- a/src/box-winUI/YMhut.Box.WinUI.csproj
+++ b/src/box-winUI/YMhut.Box.WinUI.csproj
@@ -33,7 +33,7 @@
false
-
+