diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 1c08ff3..4409015 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -113,3 +113,31 @@ jobs:
path: |
LanMountainDesktop/bin/Release/
retention-days: 7
+
+ pack-plugin-packages:
+ runs-on: ubuntu-latest
+ name: Pack_Plugin_Packages
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ submodules: recursive
+
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v4
+ with:
+ dotnet-version: ${{ env.DOTNET_VERSION }}
+
+ - name: Pack SDK and template packages
+ shell: pwsh
+ run: .\scripts\Pack-PluginPackages.ps1 -Configuration Release -OutputPath .\artifacts\nuget
+
+ - name: Upload plugin package artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: plugin-packages
+ path: artifacts/nuget/*.nupkg
+ if-no-files-found: error
+ retention-days: 14
diff --git a/LanMontainDesktop/.trae/specs/remove-video-wallpaper-feature/design.md b/LanMontainDesktop/.trae/specs/remove-video-wallpaper-feature/design.md
deleted file mode 100644
index 67a8a5c..0000000
--- a/LanMontainDesktop/.trae/specs/remove-video-wallpaper-feature/design.md
+++ /dev/null
@@ -1,578 +0,0 @@
-# 移除视频壁纸功能 - 技术设计文档
-
-## 1. 概述
-
-### 1.1 设计目标
-
-本设计文档描述如何从 LanMountainDesktop 项目中完全移除视频壁纸功能,包括:
-- 移除 LibVLC 相关依赖
-- 清理主窗口中的视频壁纸代码
-- 简化壁纸设置页面
-- 清理本地化资源
-
-### 1.2 技术约束
-
-- 保持现有图片壁纸和纯色壁纸功能完整
-- 确保应用构建和运行正常
-- 不引入新的外部依赖
-
----
-
-## 2. 架构变更
-
-### 2.1 变更概览图
-
-```
-┌─────────────────────────────────────────────────────────────────┐
-│ 变更前架构 │
-├─────────────────────────────────────────────────────────────────┤
-│ MainWindow │
-│ ├── DesktopWallpaperLayer (背景层) │
-│ │ ├── DesktopWallpaperImageLayer (图片层) │
-│ │ ├── DesktopVideoWallpaperImage (视频海报层) │
-│ │ └── DesktopVideoWallpaperView (VLC视频播放层) │
-│ ├── _libVlc, _videoWallpaperPlayer, _videoWallpaperMedia │
-│ └── StartVideoWallpaper(), StopVideoWallpaper() │
-│ │
-│ WallpaperSettingsPage │
-│ ├── 类型选择: Image | Video | SolidColor │
-│ └── 视频预览区域 │
-└─────────────────────────────────────────────────────────────────┘
-
-┌─────────────────────────────────────────────────────────────────┐
-│ 变更后架构 │
-├─────────────────────────────────────────────────────────────────┤
-│ MainWindow │
-│ ├── DesktopWallpaperLayer (背景层) │
-│ │ └── DesktopWallpaperImageLayer (图片层) │
-│ └── (移除所有视频相关字段和方法) │
-│ │
-│ WallpaperSettingsPage │
-│ ├── 类型选择: Image | SolidColor │
-│ └── (移除视频预览区域) │
-└─────────────────────────────────────────────────────────────────┘
-```
-
-### 2.2 组件变更清单
-
-| 组件 | 变更类型 | 说明 |
-|------|----------|------|
-| LanMountainDesktop.csproj | 修改 | 移除 LibVLC 包引用 |
-| MainWindow.axaml | 修改 | 移除视频控件和命名空间 |
-| MainWindow.axaml.cs | 修改 | 移除视频相关字段和清理代码 |
-| MainWindow.SettingsHardCut.Stubs.cs | 修改 | 移除视频壁纸方法 |
-| AppearanceThemeService.cs | 修改 | 移除视频种子提取器 |
-| WallpaperSettingsPage.axaml | 修改 | 移除视频类型UI |
-| WallpaperSettingsPageViewModel.cs | 修改 | 移除视频相关属性 |
-| SettingsContracts.cs | 修改 | 移除 Video 枚举值 |
-| SettingsDomainServices.cs | 修改 | 移除视频扩展名检测 |
-| zh-CN.json | 修改 | 移除视频相关本地化文本 |
-
----
-
-## 3. 详细设计
-
-### 3.1 项目依赖变更 (LanMountainDesktop.csproj)
-
-#### 3.1.1 移除的包引用
-
-```xml
-
-
-
-
-```
-
-#### 3.1.2 变更影响
-
-- 减少约 100MB+ 的依赖包大小
-- 简化构建和发布流程
-- 移除平台特定的原生库依赖
-
----
-
-### 3.2 主窗口 XAML 变更 (MainWindow.axaml)
-
-#### 3.2.1 移除命名空间声明
-
-```xml
-
-xmlns:vlc="clr-namespace:LibVLCSharp.Avalonia;assembly=LibVLCSharp.Avalonia"
-```
-
-#### 3.2.2 移除视频壁纸控件
-
-移除以下控件(约第126-137行):
-
-```xml
-
-
-
-
-
-```
-
----
-
-### 3.3 主窗口代码变更 (MainWindow.axaml.cs)
-
-#### 3.3.1 移除 using 声明
-
-```csharp
-// 移除以下 using(如果存在)
-using LibVLCSharp.Shared;
-using LibVLCSharp.Avalonia;
-```
-
-#### 3.3.2 移除静态字段
-
-```csharp
-// 移除以下字段(约第68-71行)
-private static readonly HashSet SupportedVideoExtensions = new(StringComparer.OrdinalIgnoreCase)
-{
- ".mp4", ".mkv", ".webm", ".avi", ".mov", ".m4v"
-};
-```
-
-#### 3.3.3 移除实例字段
-
-```csharp
-// 移除以下字段(约第123-146行)
-private Bitmap? _videoWallpaperPosterBitmap;
-private string? _videoWallpaperPosterPath;
-private string? _wallpaperVideoPath;
-private LibVLC? _libVlc;
-private MediaPlayer? _videoWallpaperPlayer;
-private Media? _videoWallpaperMedia;
-private readonly object _desktopVideoFrameSync = new();
-private MediaPlayer.LibVLCVideoLockCb? _desktopVideoLockCallback;
-private MediaPlayer.LibVLCVideoUnlockCb? _desktopVideoUnlockCallback;
-private MediaPlayer.LibVLCVideoDisplayCb? _desktopVideoDisplayCallback;
-private DispatcherTimer? _desktopVideoFrameRefreshTimer;
-private IntPtr _desktopVideoFrameBufferPtr;
-private byte[]? _desktopVideoStagingBuffer;
-private WriteableBitmap? _desktopVideoBitmap;
-private int _desktopVideoFrameWidth;
-private int _desktopVideoFrameHeight;
-private int _desktopVideoFramePitch;
-private int _desktopVideoFrameBufferSize;
-private int _desktopVideoFrameDirtyFlag;
-```
-
-#### 3.3.4 修改 OnClosed 方法
-
-移除视频相关清理代码(约第336-350行):
-
-```csharp
-// 移除以下代码行
-StopVideoWallpaper();
-_videoWallpaperMedia?.Dispose();
-_videoWallpaperMedia = null;
-_videoWallpaperPlayer?.Dispose();
-_videoWallpaperPlayer = null;
-_desktopVideoFrameRefreshTimer?.Stop();
-_desktopVideoFrameRefreshTimer = null;
-_videoWallpaperPosterBitmap?.Dispose();
-_videoWallpaperPosterBitmap = null;
-_videoWallpaperPosterPath = null;
-_libVlc?.Dispose();
-_libVlc = null;
-```
-
----
-
-### 3.4 主窗口 Stub 方法变更 (MainWindow.SettingsHardCut.Stubs.cs)
-
-#### 3.4.1 移除 using 声明
-
-```csharp
-// 移除以下 using(第19-20行)
-using LibVLCSharp.Shared;
-using LibVLCSharp.Avalonia;
-```
-
-#### 3.4.2 移除方法
-
-移除以下完整方法:
-
-| 方法名 | 行号范围 | 说明 |
-|--------|----------|------|
-| `StartVideoWallpaper` | 337-383 | 启动视频壁纸播放 |
-| `StopVideoWallpaper` | 385-395 | 停止视频壁纸播放 |
-| `TryCaptureVideoWallpaperPosterFrame` | 666-751 | 捕获视频海报帧 |
-| `ApplyVideoWallpaperPosterVisibility` | 647-664 | 控制视频海报可见性 |
-
-#### 3.4.3 修改 UpdateWallpaperDisplay 方法
-
-简化为仅处理图片壁纸:
-
-```csharp
-private void UpdateWallpaperDisplay()
-{
- // 移除视频分支,仅保留图片处理
- StopVideoWallpaper(); // 移除此调用
- ApplyWallpaperBrush();
-}
-```
-
-修改后:
-
-```csharp
-private void UpdateWallpaperDisplay()
-{
- ApplyWallpaperBrush();
-}
-```
-
-#### 3.4.4 修改 ApplyWallpaperBrush 方法
-
-移除所有 `ApplyVideoWallpaperPosterVisibility` 调用:
-
-```csharp
-// 移除以下调用
-ApplyVideoWallpaperPosterVisibility(showPoster: false);
-ApplyVideoWallpaperPosterVisibility(showPoster: _videoWallpaperPosterBitmap is not null);
-```
-
-#### 3.4.5 修改 SetWallpaperState 方法
-
-移除视频类型处理分支(约第238-247行):
-
-```csharp
-// 移除以下代码块
-var requestedTypeIsVideo = string.Equals(_wallpaperType, "Video", StringComparison.OrdinalIgnoreCase);
-if (SupportedVideoExtensions.Contains(extension) || requestedTypeIsVideo)
-{
- _wallpaperMediaType = WallpaperMediaType.Video;
- _wallpaperVideoPath = _wallpaperPath;
- _wallpaperDisplayState = File.Exists(_wallpaperPath)
- ? WallpaperDisplayState.CurrentValidWallpaper
- : WallpaperDisplayState.TemporarilyUnavailable;
- return;
-}
-```
-
----
-
-### 3.5 外观主题服务变更 (AppearanceThemeService.cs)
-
-#### 3.5.1 移除接口和类
-
-移除以下代码(约第92-184行):
-
-```csharp
-// 移除接口
-internal interface IVideoWallpaperSeedExtractor
-{
- IReadOnlyList ExtractSeedCandidates(string videoPath, MonetColorService monetColorService);
-}
-
-// 移除实现类
-internal sealed class LibVlcVideoWallpaperSeedExtractor : IVideoWallpaperSeedExtractor
-{
- // ... 整个类实现
-}
-```
-
----
-
-### 3.6 壁纸设置页面 XAML 变更 (WallpaperSettingsPage.axaml)
-
-#### 3.6.1 移除视频预览区域
-
-移除以下代码(约第29-44行):
-
-```xml
-
-
-
-
-
-
-```
-
-#### 3.6.2 移除视频模式提示文本
-
-移除以下代码(约第150-154行):
-
-```xml
-
-```
-
-#### 3.6.3 修改填充方式设置可见性绑定
-
-```xml
-
-IsVisible="{Binding IsImageOrVideo}"
-
-
-IsVisible="{Binding IsImage}"
-```
-
----
-
-### 3.7 壁纸设置 ViewModel 变更 (WallpaperSettingsPageViewModel.cs)
-
-#### 3.7.1 移除属性
-
-```csharp
-// 移除以下属性
-[ObservableProperty]
-private bool _isImageOrVideo;
-
-[ObservableProperty]
-private bool _isVideo;
-
-[ObservableProperty]
-private string _videoModeHintText = string.Empty;
-```
-
-#### 3.7.2 修改 CreateWallpaperTypes 方法
-
-```csharp
-// 修改前
-private IReadOnlyList CreateWallpaperTypes()
-{
- return
- [
- new SelectionOption("Image", L("settings.wallpaper.type.image", "Image")),
- new SelectionOption("Video", L("settings.wallpaper.type.video", "Video")),
- new SelectionOption("SolidColor", L("settings.wallpaper.type.solid_color", "Solid Color"))
- ];
-}
-
-// 修改后
-private IReadOnlyList CreateWallpaperTypes()
-{
- return
- [
- new SelectionOption("Image", L("settings.wallpaper.type.image", "Image")),
- new SelectionOption("SolidColor", L("settings.wallpaper.type.solid_color", "Solid Color"))
- ];
-}
-```
-
-#### 3.7.3 修改 UpdateVisibility 方法
-
-移除 IsVideo 和 IsImageOrVideo 的赋值:
-
-```csharp
-// 移除以下行
-IsVideo = SelectedWallpaperType?.Value == "Video";
-IsImageOrVideo = SelectedWallpaperType?.Value is "Image" or "Video";
-```
-
-#### 3.7.4 修改 RefreshLocalizedText 方法
-
-```csharp
-// 移除以下行
-VideoModeHintText = L("settings.wallpaper.video_mode", "Video wallpaper uses automatic fill mode.");
-```
-
----
-
-### 3.8 设置契约变更 (SettingsContracts.cs)
-
-#### 3.8.1 修改 WallpaperMediaType 枚举
-
-```csharp
-// 修改前
-public enum WallpaperMediaType
-{
- None,
- Image,
- Video
-}
-
-// 修改后
-public enum WallpaperMediaType
-{
- None,
- Image
-}
-```
-
----
-
-### 3.9 设置域服务变更 (SettingsDomainServices.cs)
-
-#### 3.9.1 移除视频扩展名集合
-
-```csharp
-// 移除以下字段(约第150-153行)
-private static readonly HashSet VideoExtensions = new(StringComparer.OrdinalIgnoreCase)
-{
- ".mp4", ".mkv", ".webm", ".avi", ".mov", ".m4v"
-};
-```
-
-#### 3.9.2 修改 DetectMediaType 方法
-
-```csharp
-// 修改前
-public WallpaperMediaType DetectMediaType(string? path)
-{
- if (string.IsNullOrWhiteSpace(path))
- {
- return WallpaperMediaType.None;
- }
-
- var extension = Path.GetExtension(path.Trim());
- if (string.IsNullOrWhiteSpace(extension))
- {
- return WallpaperMediaType.None;
- }
-
- if (ImageExtensions.Contains(extension))
- {
- return WallpaperMediaType.Image;
- }
-
- if (VideoExtensions.Contains(extension))
- {
- return WallpaperMediaType.Video;
- }
-
- return WallpaperMediaType.None;
-}
-
-// 修改后
-public WallpaperMediaType DetectMediaType(string? path)
-{
- if (string.IsNullOrWhiteSpace(path))
- {
- return WallpaperMediaType.None;
- }
-
- var extension = Path.GetExtension(path.Trim());
- if (string.IsNullOrWhiteSpace(extension))
- {
- return WallpaperMediaType.None;
- }
-
- if (ImageExtensions.Contains(extension))
- {
- return WallpaperMediaType.Image;
- }
-
- return WallpaperMediaType.None;
-}
-```
-
----
-
-### 3.10 本地化文件变更 (zh-CN.json)
-
-#### 3.10.1 移除的本地化键
-
-```json
-// 移除以下键值对
-"settings.wallpaper.type.video": "视频",
-"settings.wallpaper.video_applied": "视频壁纸已应用。",
-"settings.wallpaper.video_mode": "视频壁纸使用自动填充模式。",
-"settings.wallpaper.video_restored": "已恢复保存的视频壁纸。",
-"settings.wallpaper.video_not_found": "未找到视频壁纸文件。",
-"settings.wallpaper.video_player_unavailable": "视频播放器不可用。",
-"settings.wallpaper.video_play_failed_format": "播放视频壁纸失败:{0}"
-```
-
-#### 3.10.2 修改描述文本
-
-```json
-// 修改前
-"settings.wallpaper.description": "选择图片或视频后可立即设为应用窗口壁纸。",
-
-// 修改后
-"settings.wallpaper.description": "选择图片后可立即设为应用窗口壁纸。",
-```
-
----
-
-## 4. 数据模型变更
-
-### 4.1 WallpaperMediaType 枚举简化
-
-```
-变更前: None | Image | Video
-变更后: None | Image
-```
-
-### 4.2 设置存储兼容性
-
-现有用户设置中如果包含 `Type: "Video"` 的壁纸配置:
-- 应用将无法识别该类型
-- 将回退到纯色背景
-- 用户需要重新选择图片壁纸
-
----
-
-## 5. 风险评估
-
-### 5.1 潜在风险
-
-| 风险 | 影响 | 缓解措施 |
-|------|------|----------|
-| 现有视频壁纸用户设置失效 | 中 | 应用会自动回退到纯色背景 |
-| 遗漏的视频相关代码引用 | 低 | 编译器会报告未定义类型错误 |
-| 本地化键遗漏 | 低 | 运行时会显示键名而非翻译文本 |
-
-### 5.2 回滚策略
-
-如需回滚,可通过 Git 恢复以下文件:
-- LanMountainDesktop.csproj
-- MainWindow.axaml / .axaml.cs
-- MainWindow.SettingsHardCut.Stubs.cs
-- AppearanceThemeService.cs
-- WallpaperSettingsPage.axaml
-- WallpaperSettingsPageViewModel.cs
-- SettingsContracts.cs
-- SettingsDomainServices.cs
-- zh-CN.json
-
----
-
-## 6. 验证清单
-
-### 6.1 编译验证
-
-- [ ] 项目编译无错误
-- [ ] 无 LibVLC 相关类型引用警告
-- [ ] 无未使用变量警告
-
-### 6.2 功能验证
-
-- [ ] 应用正常启动
-- [ ] 图片壁纸正常显示
-- [ ] 纯色壁纸正常显示
-- [ ] 壁纸设置页面正常打开
-- [ ] 类型选择器仅显示"图片"和"纯色"
-- [ ] 壁纸导入功能正常工作
-
-### 6.3 清理验证
-
-- [ ] 无 LibVLC 相关 DLL 在输出目录
-- [ ] 无视频相关本地化文本残留
-- [ ] 无视频相关 UI 控件残留
diff --git a/LanMontainDesktop/.trae/specs/remove-video-wallpaper-feature/spec.md b/LanMontainDesktop/.trae/specs/remove-video-wallpaper-feature/spec.md
deleted file mode 100644
index d5cb620..0000000
--- a/LanMontainDesktop/.trae/specs/remove-video-wallpaper-feature/spec.md
+++ /dev/null
@@ -1,206 +0,0 @@
-# 移除视频壁纸功能规格说明书
-
-## Why
-
-当前 LanMountainDesktop 项目包含视频壁纸功能,该功能引入了以下复杂性和依赖:
-1. 引入了 LibVLCSharp.Avalonia、VideoLAN.LibVLC.Windows、VideoLAN.LibVLC.Mac 等重型依赖
-2. 在主窗口中残留大量视频壁纸相关代码和字段
-3. 在设置页面中保留了视频类型选择器和相关 UI 元素
-4. 在本地化文件中保留了视频壁纸相关文本
-5. 增加了应用复杂度和维护成本
-
-用户决定移除该功能以简化代码库。
-
-## What Changes
-
-- 移除 LibVLCSharp.Avalonia 及 VideoLAN.LibVLC.* NuGet 依赖
-- 移除 AppearanceThemeService.cs 中的 LibVlcVideoWallpaperSeedExtractor 类和 IVideoWallpaperSeedExtractor 接口
-- 移除 MainWindow.axaml.cs 中的视频壁纸相关字段和清理代码
-- 移除 MainWindow.SettingsHardCut.Stubs.cs 中的视频壁纸相关方法
-- 移除 MainWindow.axaml 中的 DesktopVideoWallpaperImage 和 DesktopVideoWallpaperView 控件
-- 移除 WallpaperSettingsPage.axaml 中的视频类型选择器和视频模式提示
-- 移除 WallpaperSettingsPageViewModel.cs 中的 IsVideo、VideoModeHintText 等属性
-- 移除 SettingsContracts.cs 中 WallpaperMediaType 枚举的 Video 值
-- 移除 SettingsDomainServices.cs 中 WallpaperMediaService 类的视频扩展名检测逻辑
-- 移除本地化文件中的视频壁纸相关文本
-
-## Impact
-
-### Affected specs
-- 壁纸设置功能规格
-- 主窗口桌面层规格
-
-### Affected code
-- `LanMountainDesktop.csproj` - NuGet 依赖配置
-- `Services/AppearanceThemeService.cs` - 视频壁纸种子提取器
-- `Views/MainWindow.axaml.cs` - 主窗口字段和清理逻辑
-- `Views/MainWindow.SettingsHardCut.Stubs.cs` - 视频壁纸控制方法
-- `Views/MainWindow.axaml` - 视频壁纸 UI 控件
-- `Views/SettingsPages/WallpaperSettingsPage.axaml` - 壁纸设置页面 UI
-- `ViewModels/WallpaperSettingsPageViewModel.cs` - 壁纸设置 ViewModel
-- `Services/Settings/SettingsContracts.cs` - 壁纸媒体类型枚举
-- `Services/Settings/SettingsDomainServices.cs` - 壁纸媒体服务
-- `Localization/zh-CN.json` - 本地化文本
-
----
-
-## REMOVED Requirements
-
-### Requirement: 视频壁纸播放功能
-
-**Reason**: 用户决定移除视频壁纸功能以简化代码库,减少重型依赖
-
-**Migration**:
-- 用户如需动态壁纸,可使用静态图片壁纸替代
-- 现有视频壁纸设置将被重置为纯色背景
-
-#### Scenario: 视频壁纸播放
-- **GIVEN** 用户选择了视频文件作为壁纸
-- **WHEN** 系统检测到视频格式
-- **THEN** 系统不再支持视频壁纸播放
-- **AND THEN** 系统提示用户该文件类型不受支持
-
-### Requirement: LibVLC 依赖
-
-**Reason**: 移除视频壁纸功能后不再需要 LibVLC 库
-
-**Migration**: 从项目依赖中移除以下包:
-- LibVLCSharp.Avalonia
-- VideoLAN.LibVLC.Windows
-- VideoLAN.LibVLC.Mac
-
-### Requirement: 视频壁纸种子提取
-
-**Reason**: 移除视频壁纸功能后不再需要从视频中提取颜色种子
-
-**Migration**: 移除 `LibVlcVideoWallpaperSeedExtractor` 类和 `IVideoWallpaperSeedExtractor` 接口
-
-### Requirement: 视频壁纸 UI 控件
-
-**Reason**: 移除视频壁纸功能后不再需要视频显示控件
-
-**Migration**: 移除 `DesktopVideoWallpaperImage` 和 `DesktopVideoWallpaperView` 控件
-
-### Requirement: 视频类型选择器
-
-**Reason**: 移除视频壁纸功能后不再需要视频类型选项
-
-**Migration**: 从壁纸类型选择器中移除"视频"选项
-
----
-
-## MODIFIED Requirements
-
-### Requirement: 壁纸媒体类型检测
-
-**当前**: 支持检测 None、Image、Video 三种类型
-
-**修改后**: 仅支持检测 None、Image 两种类型
-
-#### Scenario: 检测媒体类型
-- **WHEN** 用户选择壁纸文件
-- **THEN** 系统仅检测图片格式(.png, .jpg, .jpeg, .bmp, .gif, .webp)
-- **AND THEN** 视频格式文件将被识别为不受支持的类型
-
-### Requirement: 壁纸类型选项
-
-**当前**: 提供图片、视频、纯色三种类型选项
-
-**修改后**: 仅提供图片、纯色两种类型选项
-
-#### Scenario: 壁纸类型选择
-- **WHEN** 用户打开壁纸设置页面
-- **THEN** 类型选择器仅显示"图片"和"纯色"选项
-- **AND THEN** "视频"选项不再显示
-
-### Requirement: 壁纸设置页面预览
-
-**当前**: 根据类型显示图片预览、视频预览或纯色预览
-
-**修改后**: 根据类型显示图片预览或纯色预览
-
-#### Scenario: 预览显示
-- **WHEN** 用户选择壁纸类型
-- **THEN** 系统仅显示图片预览或纯色预览
-- **AND THEN** 视频预览区域不再显示
-
-### Requirement: 主窗口壁纸显示
-
-**当前**: 支持显示静态图片壁纸和视频壁纸
-
-**修改后**: 仅支持显示静态图片壁纸
-
-#### Scenario: 壁纸显示更新
-- **WHEN** 用户应用新壁纸
-- **THEN** 系统仅处理静态图片壁纸显示
-- **AND THEN** 视频壁纸播放逻辑不再执行
-
----
-
-## ADDED Requirements
-
-### Requirement: 清理残留代码
-
-系统 SHALL 完全移除视频壁纸功能相关的所有代码和资源。
-
-#### Scenario: 主窗口字段清理
-- **WHEN** 执行代码清理
-- **THEN** 移除以下字段:
- - `_videoWallpaperPosterBitmap`
- - `_videoWallpaperPosterPath`
- - `_libVlc`
- - `_videoWallpaperPlayer`
- - `_videoWallpaperMedia`
- - `_wallpaperVideoPath`
-
-#### Scenario: 主窗口方法清理
-- **WHEN** 执行代码清理
-- **THEN** 移除以下方法:
- - `StartVideoWallpaper`
- - `StopVideoWallpaper`
- - `TryCaptureVideoWallpaperPosterFrame`
- - `ApplyVideoWallpaperPosterVisibility`
- - `UpdateWallpaperDisplay` 中的视频处理分支
-
-#### Scenario: ViewModel 属性清理
-- **WHEN** 执行代码清理
-- **THEN** 移除以下属性:
- - `IsVideo`
- - `VideoModeHintText`
- - `IsImageOrVideo`(改为 `IsImage`)
-
-#### Scenario: 本地化文本清理
-- **WHEN** 执行代码清理
-- **THEN** 移除以下本地化键:
- - `settings.wallpaper.type.video`
- - `settings.wallpaper.video_applied`
- - `settings.wallpaper.video_mode`
- - `settings.wallpaper.video_restored`
- - `settings.wallpaper.video_not_found`
- - `settings.wallpaper.video_player_unavailable`
- - `settings.wallpaper.video_play_failed_format`
-
-### Requirement: 依赖项清理
-
-系统 SHALL 从项目文件中移除 LibVLC 相关 NuGet 包引用。
-
-#### Scenario: NuGet 包移除
-- **WHEN** 执行依赖清理
-- **THEN** 移除以下包引用:
- - `LibVLCSharp.Avalonia`
- - `VideoLAN.LibVLC.Windows`
- - `VideoLAN.LibVLC.Mac`
-
-### Requirement: 构建验证
-
-系统 SHALL 在移除视频壁纸功能后保持正常构建和运行。
-
-#### Scenario: 构建成功
-- **WHEN** 执行项目构建
-- **THEN** 构建成功无错误
-- **AND THEN** 所有现有测试通过
-
-#### Scenario: 应用启动
-- **WHEN** 启动应用程序
-- **THEN** 应用正常启动
-- **AND THEN** 壁纸设置功能正常工作(仅支持图片和纯色)
diff --git a/LanMontainDesktop/.trae/specs/remove-video-wallpaper-feature/tasks.md b/LanMontainDesktop/.trae/specs/remove-video-wallpaper-feature/tasks.md
deleted file mode 100644
index 3eb0e79..0000000
--- a/LanMontainDesktop/.trae/specs/remove-video-wallpaper-feature/tasks.md
+++ /dev/null
@@ -1,600 +0,0 @@
-# 移除视频壁纸功能 - 编码任务清单
-
-## 任务概览
-
-本文档将技术设计分解为可执行的编码任务,按依赖关系排序执行。
-
----
-
-## 任务 1: 移除项目依赖
-
-**优先级**: P0 (最高)
-**依赖**: 无
-**预估工作量**: 5 分钟
-
-### 描述
-
-从项目文件中移除 LibVLC 相关的 NuGet 包引用。
-
-### 输入
-
-- `LanMountainDesktop/LanMountainDesktop.csproj`
-
-### 输出
-
-- 修改后的 `LanMountainDesktop.csproj`,移除以下包引用:
- - `LibVLCSharp.Avalonia`
- - `VideoLAN.LibVLC.Windows`
- - `VideoLAN.LibVLC.Mac`
-
-### 验收标准
-
-- [ ] 项目文件中不再包含 LibVLC 相关包引用
-- [ ] 执行 `dotnet restore` 成功
-
-### 执行提示
-
-```
-编辑 LanMountainDesktop.csproj,移除以下 PackageReference 节点:
-1.
-2.
-3.
-```
-
----
-
-## 任务 2: 移除主窗口 XAML 视频控件
-
-**优先级**: P0
-**依赖**: 任务 1
-**预估工作量**: 10 分钟
-
-### 描述
-
-从 MainWindow.axaml 中移除视频壁纸相关的 XAML 控件和命名空间声明。
-
-### 输入
-
-- `LanMountainDesktop/Views/MainWindow.axaml`
-
-### 输出
-
-- 移除 LibVLC 命名空间声明
-- 移除 `DesktopVideoWallpaperImage` 控件
-- 移除 `DesktopVideoWallpaperView` 控件
-
-### 验收标准
-
-- [ ] XAML 中无 `xmlns:vlc` 命名空间
-- [ ] XAML 中无 `DesktopVideoWallpaperImage` 元素
-- [ ] XAML 中无 `DesktopVideoWallpaperView` 元素
-
-### 执行提示
-
-```
-编辑 MainWindow.axaml:
-1. 移除第 9 行: xmlns:vlc="clr-namespace:LibVLCSharp.Avalonia;assembly=LibVLCSharp.Avalonia"
-2. 移除第 126-131 行:
-3. 移除第 133-137 行:
-```
-
----
-
-## 任务 3: 移除主窗口代码视频字段
-
-**优先级**: P0
-**依赖**: 任务 1
-**预估工作量**: 15 分钟
-
-### 描述
-
-从 MainWindow.axaml.cs 中移除视频壁纸相关的字段声明。
-
-### 输入
-
-- `LanMountainDesktop/Views/MainWindow.axaml.cs`
-
-### 输出
-
-- 移除 `SupportedVideoExtensions` 静态字段
-- 移除所有视频相关实例字段
-
-### 验收标准
-
-- [ ] 无 `SupportedVideoExtensions` 字段
-- [ ] 无 `_videoWallpaperPosterBitmap` 字段
-- [ ] 无 `_videoWallpaperPosterPath` 字段
-- [ ] 无 `_wallpaperVideoPath` 字段
-- [ ] 无 `_libVlc` 字段
-- [ ] 无 `_videoWallpaperPlayer` 字段
-- [ ] 无 `_videoWallpaperMedia` 字段
-- [ ] 无 `_desktopVideoFrameSync` 及相关视频帧处理字段
-
-### 执行提示
-
-```
-编辑 MainWindow.axaml.cs:
-1. 移除第 68-71 行的 SupportedVideoExtensions 定义
-2. 移除第 123-146 行的所有视频相关字段
-```
-
----
-
-## 任务 4: 移除主窗口 OnClosed 清理代码
-
-**优先级**: P0
-**依赖**: 任务 3
-**预估工作量**: 5 分钟
-
-### 描述
-
-从 MainWindow.axaml.cs 的 OnClosed 方法中移除视频相关清理代码。
-
-### 输入
-
-- `LanMountainDesktop/Views/MainWindow.axaml.cs` (OnClosed 方法)
-
-### 输出
-
-- 简化的 OnClosed 方法,无视频清理逻辑
-
-### 验收标准
-
-- [ ] OnClosed 方法中无 `StopVideoWallpaper()` 调用
-- [ ] OnClosed 方法中无 `_videoWallpaperMedia` 相关清理
-- [ ] OnClosed 方法中无 `_videoWallpaperPlayer` 相关清理
-- [ ] OnClosed 方法中无 `_libVlc` 相关清理
-
-### 执行提示
-
-```
-编辑 MainWindow.axaml.cs 的 OnClosed 方法,移除以下代码行:
-- StopVideoWallpaper();
-- _videoWallpaperMedia?.Dispose(); _videoWallpaperMedia = null;
-- _videoWallpaperPlayer?.Dispose(); _videoWallpaperPlayer = null;
-- _desktopVideoFrameRefreshTimer?.Stop(); _desktopVideoFrameRefreshTimer = null;
-- _videoWallpaperPosterBitmap?.Dispose(); _videoWallpaperPosterBitmap = null;
-- _videoWallpaperPosterPath = null;
-- _libVlc?.Dispose(); _libVlc = null;
-```
-
----
-
-## 任务 5: 移除主窗口 Stub 方法
-
-**优先级**: P0
-**依赖**: 任务 1
-**预估工作量**: 20 分钟
-
-### 描述
-
-从 MainWindow.SettingsHardCut.Stubs.cs 中移除视频壁纸相关方法和 using 声明。
-
-### 输入
-
-- `LanMountainDesktop/Views/MainWindow.SettingsHardCut.Stubs.cs`
-
-### 输出
-
-- 移除 LibVLC using 声明
-- 移除 `StartVideoWallpaper` 方法
-- 移除 `StopVideoWallpaper` 方法
-- 移除 `TryCaptureVideoWallpaperPosterFrame` 方法
-- 移除 `ApplyVideoWallpaperPosterVisibility` 方法
-
-### 验收标准
-
-- [ ] 无 `using LibVLCSharp.Shared;`
-- [ ] 无 `using LibVLCSharp.Avalonia;`
-- [ ] 无 `StartVideoWallpaper` 方法定义
-- [ ] 无 `StopVideoWallpaper` 方法定义
-- [ ] 无 `TryCaptureVideoWallpaperPosterFrame` 方法定义
-- [ ] 无 `ApplyVideoWallpaperPosterVisibility` 方法定义
-
-### 执行提示
-
-```
-编辑 MainWindow.SettingsHardCut.Stubs.cs:
-1. 移除第 19-20 行的 using 声明
-2. 移除 StartVideoWallpaper 方法(第 337-383 行)
-3. 移除 StopVideoWallpaper 方法(第 385-395 行)
-4. 移除 ApplyVideoWallpaperPosterVisibility 方法(第 647-664 行)
-5. 移除 TryCaptureVideoWallpaperPosterFrame 方法(第 666-751 行)
-```
-
----
-
-## 任务 6: 简化壁纸状态处理逻辑
-
-**优先级**: P0
-**依赖**: 任务 5
-**预估工作量**: 15 分钟
-
-### 描述
-
-修改 MainWindow.SettingsHardCut.Stubs.cs 中的壁纸状态处理方法,移除视频类型分支。
-
-### 输入
-
-- `LanMountainDesktop/Views/MainWindow.SettingsHardCut.Stubs.cs`
-
-### 输出
-
-- 简化的 `SetWallpaperState` 方法
-- 简化的 `UpdateWallpaperDisplay` 方法
-- 简化的 `ApplyWallpaperBrush` 方法
-
-### 验收标准
-
-- [ ] `SetWallpaperState` 中无视频类型检测分支
-- [ ] `SetWallpaperState` 中无 `_wallpaperVideoPath` 赋值
-- [ ] `UpdateWallpaperDisplay` 中无 `StopVideoWallpaper()` 调用
-- [ ] `ApplyWallpaperBrush` 中无 `ApplyVideoWallpaperPosterVisibility` 调用
-
-### 执行提示
-
-```
-编辑 MainWindow.SettingsHardCut.Stubs.cs:
-
-1. SetWallpaperState 方法:
- - 移除 requestedTypeIsVideo 变量定义
- - 移除视频类型检测 if 块(SupportedVideoExtensions.Contains 检查)
-
-2. UpdateWallpaperDisplay 方法:
- - 移除视频类型分支,仅保留 ApplyWallpaperBrush() 调用
-
-3. ApplyWallpaperBrush 方法:
- - 移除所有 ApplyVideoWallpaperPosterVisibility 调用
-```
-
----
-
-## 任务 7: 移除外观主题服务视频提取器
-
-**优先级**: P1
-**依赖**: 任务 1
-**预估工作量**: 10 分钟
-
-### 描述
-
-从 AppearanceThemeService.cs 中移除视频壁纸种子提取器接口和实现类。
-
-### 输入
-
-- `LanMountainDesktop/Services/AppearanceThemeService.cs`
-
-### 输出
-
-- 移除 `IVideoWallpaperSeedExtractor` 接口
-- 移除 `LibVlcVideoWallpaperSeedExtractor` 类
-
-### 验收标准
-
-- [ ] 无 `IVideoWallpaperSeedExtractor` 接口定义
-- [ ] 无 `LibVlcVideoWallpaperSeedExtractor` 类定义
-
-### 执行提示
-
-```
-编辑 AppearanceThemeService.cs:
-移除第 92-184 行的接口和类定义:
-- IVideoWallpaperSeedExtractor 接口
-- LibVlcVideoWallpaperSeedExtractor 类
-```
-
----
-
-## 任务 8: 简化壁纸设置页面 XAML
-
-**优先级**: P1
-**依赖**: 无
-**预估工作量**: 10 分钟
-
-### 描述
-
-从 WallpaperSettingsPage.axaml 中移除视频预览区域和相关 UI 元素。
-
-### 输入
-
-- `LanMountainDesktop/Views/SettingsPages/WallpaperSettingsPage.axaml`
-
-### 输出
-
-- 移除视频预览 Border 区域
-- 移除视频模式提示 TextBlock
-- 修改填充方式可见性绑定
-
-### 验收标准
-
-- [ ] 无视频预览 Border(IsVisible="{Binding IsVideo}")
-- [ ] 无 VideoModeHintText 绑定的 TextBlock
-- [ ] 填充方式设置绑定改为 `IsVisible="{Binding IsImage}"`
-
-### 执行提示
-
-```
-编辑 WallpaperSettingsPage.axaml:
-1. 移除第 29-44 行的视频预览 Border
-2. 移除第 150-154 行的视频模式提示 TextBlock
-3. 修改第 132 行: IsVisible="{Binding IsImageOrVideo}" 改为 IsVisible="{Binding IsImage}"
-```
-
----
-
-## 任务 9: 简化壁纸设置 ViewModel
-
-**优先级**: P1
-**依赖**: 任务 8
-**预估工作量**: 15 分钟
-
-### 描述
-
-从 WallpaperSettingsPageViewModel.cs 中移除视频相关属性和方法逻辑。
-
-### 输入
-
-- `LanMountainDesktop/ViewModels/WallpaperSettingsPageViewModel.cs`
-
-### 输出
-
-- 移除 `_isImageOrVideo`、`_isVideo`、`_videoModeHintText` 属性
-- 修改 `CreateWallpaperTypes` 方法
-- 修改 `UpdateVisibility` 方法
-- 修改 `RefreshLocalizedText` 方法
-
-### 验收标准
-
-- [ ] 无 `IsImageOrVideo` 属性
-- [ ] 无 `IsVideo` 属性
-- [ ] 无 `VideoModeHintText` 属性
-- [ ] `CreateWallpaperTypes` 仅返回 Image 和 SolidColor 选项
-- [ ] `UpdateVisibility` 中无 IsVideo、IsImageOrVideo 赋值
-- [ ] `RefreshLocalizedText` 中无 VideoModeHintText 赋值
-
-### 执行提示
-
-```
-编辑 WallpaperSettingsPageViewModel.cs:
-1. 移除第 76-77 行的 _isImageOrVideo 字段和属性
-2. 移除第 85-86 行的 _isVideo 字段和属性
-3. 移除第 94-95 行的 _videoModeHintText 字段和属性
-4. 修改 CreateWallpaperTypes 方法,移除 Video 选项
-5. 修改 UpdateVisibility 方法,移除 IsVideo 和 IsImageOrVideo 赋值
-6. 修改 RefreshLocalizedText 方法,移除 VideoModeHintText 赋值
-```
-
----
-
-## 任务 10: 简化壁纸媒体类型枚举
-
-**优先级**: P1
-**依赖**: 无
-**预估工作量**: 5 分钟
-
-### 描述
-
-从 SettingsContracts.cs 中移除 WallpaperMediaType 枚举的 Video 值。
-
-### 输入
-
-- `LanMountainDesktop/Services/Settings/SettingsContracts.cs`
-
-### 输出
-
-- 简化的 `WallpaperMediaType` 枚举
-
-### 验收标准
-
-- [ ] `WallpaperMediaType` 枚举仅包含 `None` 和 `Image`
-
-### 执行提示
-
-```
-编辑 SettingsContracts.cs:
-修改第 11-16 行的枚举定义:
-public enum WallpaperMediaType
-{
- None,
- Image
-}
-```
-
----
-
-## 任务 11: 简化壁纸媒体服务
-
-**优先级**: P1
-**依赖**: 任务 10
-**预估工作量**: 10 分钟
-
-### 描述
-
-从 SettingsDomainServices.cs 中移除视频扩展名检测逻辑。
-
-### 输入
-
-- `LanMountainDesktop/Services/Settings/SettingsDomainServices.cs`
-
-### 输出
-
-- 移除 `VideoExtensions` 字段
-- 简化 `DetectMediaType` 方法
-
-### 验收标准
-
-- [ ] 无 `VideoExtensions` 字段定义
-- [ ] `DetectMediaType` 方法中无视频扩展名检测逻辑
-
-### 执行提示
-
-```
-编辑 SettingsDomainServices.cs:
-1. 移除第 150-153 行的 VideoExtensions 字段定义
-2. 修改 DetectMediaType 方法,移除视频检测分支
-```
-
----
-
-## 任务 12: 清理本地化文件
-
-**优先级**: P2
-**依赖**: 无
-**预估工作量**: 5 分钟
-
-### 描述
-
-从 zh-CN.json 中移除视频壁纸相关的本地化文本。
-
-### 输入
-
-- `LanMountainDesktop/Localization/zh-CN.json`
-
-### 输出
-
-- 移除视频相关本地化键
-- 修改壁纸描述文本
-
-### 验收标准
-
-- [ ] 无 `settings.wallpaper.type.video` 键
-- [ ] 无 `settings.wallpaper.video_applied` 键
-- [ ] 无 `settings.wallpaper.video_mode` 键
-- [ ] 无 `settings.wallpaper.video_restored` 键
-- [ ] 无 `settings.wallpaper.video_not_found` 键
-- [ ] 无 `settings.wallpaper.video_player_unavailable` 键
-- [ ] 无 `settings.wallpaper.video_play_failed_format` 键
-- [ ] `settings.wallpaper.description` 文本已更新
-
-### 执行提示
-
-```
-编辑 zh-CN.json:
-1. 移除以下键值对:
- - "settings.wallpaper.type.video"
- - "settings.wallpaper.video_applied"
- - "settings.wallpaper.video_mode"
- - "settings.wallpaper.video_restored"
- - "settings.wallpaper.video_not_found"
- - "settings.wallpaper.video_player_unavailable"
- - "settings.wallpaper.video_play_failed_format"
-
-2. 修改描述文本:
- "settings.wallpaper.description": "选择图片后可立即设为应用窗口壁纸。"
-```
-
----
-
-## 任务 13: 构建验证
-
-**优先级**: P0
-**依赖**: 任务 1-12 全部完成
-**预估工作量**: 10 分钟
-
-### 描述
-
-验证项目在移除视频壁纸功能后能够正常构建。
-
-### 输入
-
-- 整个项目
-
-### 输出
-
-- 构建成功确认
-
-### 验收标准
-
-- [ ] `dotnet build` 执行成功,无编译错误
-- [ ] 无 LibVLC 相关类型未定义错误
-- [ ] 无未使用变量警告(或已处理)
-
-### 执行提示
-
-```
-在项目根目录执行:
-dotnet build LanMountainDesktop/LanMountainDesktop.csproj
-
-检查输出:
-- 确认无编译错误
-- 确认无 LibVLC 相关类型引用错误
-```
-
----
-
-## 任务 14: 功能验证
-
-**优先级**: P0
-**依赖**: 任务 13
-**预估工作量**: 15 分钟
-
-### 描述
-
-验证应用在移除视频壁纸功能后核心功能正常工作。
-
-### 输入
-
-- 构建后的应用
-
-### 输出
-
-- 功能验证报告
-
-### 验收标准
-
-- [ ] 应用正常启动
-- [ ] 图片壁纸正常显示
-- [ ] 纯色壁纸正常显示
-- [ ] 壁纸设置页面正常打开
-- [ ] 类型选择器仅显示"图片"和"纯色"选项
-- [ ] 壁纸导入功能正常工作
-
-### 执行提示
-
-```
-运行应用:
-dotnet run --project LanMountainDesktop/LanMountainDesktop.csproj
-
-手动验证:
-1. 应用启动无崩溃
-2. 打开设置 -> 壁纸页面
-3. 确认类型选择器仅有"图片"和"纯色"
-4. 测试选择图片壁纸
-5. 测试选择纯色壁纸
-```
-
----
-
-## 任务依赖关系图
-
-```
-任务 1 (移除依赖)
- ├── 任务 2 (XAML控件)
- ├── 任务 3 (代码字段)
- │ └── 任务 4 (OnClosed清理)
- ├── 任务 5 (Stub方法)
- │ └── 任务 6 (状态处理逻辑)
- └── 任务 7 (主题服务)
-
-任务 8 (设置页面XAML)
- └── 任务 9 (设置ViewModel)
-
-任务 10 (枚举简化)
- └── 任务 11 (媒体服务)
-
-任务 12 (本地化) - 独立
-
-任务 13 (构建验证) - 依赖所有任务
- └── 任务 14 (功能验证)
-```
-
----
-
-## 执行顺序建议
-
-按以下顺序执行可确保依赖关系正确:
-
-1. **第一批** (可并行): 任务 1, 任务 8, 任务 10, 任务 12
-2. **第二批** (可并行): 任务 2, 任务 3, 任务 5, 任务 7, 任务 9, 任务 11
-3. **第三批** (可并行): 任务 4, 任务 6
-4. **第四批**: 任务 13
-5. **第五批**: 任务 14
diff --git a/LanMountainDesktop.PluginSdk/LanMountainDesktop.PluginSdk.csproj b/LanMountainDesktop.PluginSdk/LanMountainDesktop.PluginSdk.csproj
index d3dc722..292fb62 100644
--- a/LanMountainDesktop.PluginSdk/LanMountainDesktop.PluginSdk.csproj
+++ b/LanMountainDesktop.PluginSdk/LanMountainDesktop.PluginSdk.csproj
@@ -4,7 +4,15 @@
net10.0
enable
enable
- 3.0.0
+ 4.0.0
+ LanMountainDesktop.PluginSdk
+ true
+ LanMountainDesktop
+ Official plugin SDK for LanMountainDesktop, including plugin manifest contracts, runtime interfaces, and registration extensions.
+ LanMountainDesktop;Plugin;SDK;Avalonia
+ README.md
+ https://github.com/wwiinnddyy/LanMountainDesktop
+ git
@@ -15,4 +23,10 @@
+
+
+
+
+
+
diff --git a/LanMountainDesktop.PluginSdk/README.md b/LanMountainDesktop.PluginSdk/README.md
new file mode 100644
index 0000000..4717217
--- /dev/null
+++ b/LanMountainDesktop.PluginSdk/README.md
@@ -0,0 +1,21 @@
+# LanMountainDesktop.PluginSdk
+
+Official SDK package for LanMountainDesktop plugins.
+
+## Includes
+
+- `IPlugin`/`PluginBase` entry abstractions
+- `PluginManifest` and shared contract declarations
+- desktop component registration extensions
+- plugin runtime context and host service abstractions
+- build-transitive packaging targets for `.laapp` output
+
+## Quick Start
+
+```xml
+
+
+
+```
+
+Create `plugin.json` in your plugin project root, then run `dotnet build` to produce both build output and a `.laapp` package.
diff --git a/LanMountainDesktop.PluginSdk/buildTransitive/LanMountainDesktop.PluginSdk.props b/LanMountainDesktop.PluginSdk/buildTransitive/LanMountainDesktop.PluginSdk.props
new file mode 100644
index 0000000..753846f
--- /dev/null
+++ b/LanMountainDesktop.PluginSdk/buildTransitive/LanMountainDesktop.PluginSdk.props
@@ -0,0 +1,14 @@
+
+
+ plugin.json
+ .laapp
+ $(MSBuildProjectDirectory)\
+
+ true
+ false
+
+
+
+
+
+
diff --git a/LanMountainDesktop.PluginSdk/buildTransitive/LanMountainDesktop.PluginSdk.targets b/LanMountainDesktop.PluginSdk/buildTransitive/LanMountainDesktop.PluginSdk.targets
new file mode 100644
index 0000000..53b88b2
--- /dev/null
+++ b/LanMountainDesktop.PluginSdk/buildTransitive/LanMountainDesktop.PluginSdk.targets
@@ -0,0 +1,51 @@
+
+
+
+
+
+
+
+ <_LanMountainPluginBuildOutputDirectory>$(LanMountainPluginBuildOutputDirectory)
+ <_LanMountainPluginBuildOutputDirectory Condition="'$(_LanMountainPluginBuildOutputDirectory)' == ''">$(TargetDir)
+ <_LanMountainPluginBuildOutputDirectory Condition="'$(_LanMountainPluginBuildOutputDirectory)' == ''">$(MSBuildProjectDirectory)\$(OutputPath)
+ <_LanMountainPluginAssemblyName>$(LanMountainPluginAssemblyName)
+ <_LanMountainPluginAssemblyName Condition="'$(_LanMountainPluginAssemblyName)' == '' and '$(AssemblyName)' != ''">$(AssemblyName)
+ <_LanMountainPluginAssemblyName Condition="'$(_LanMountainPluginAssemblyName)' == ''">$(MSBuildProjectName)
+ <_LanMountainPluginPackageVersion>$(LanMountainPluginPackageVersion)
+ <_LanMountainPluginPackageVersion Condition="'$(_LanMountainPluginPackageVersion)' == '' and '$(Version)' != ''">$(Version)
+ <_LanMountainPluginPackageVersion Condition="'$(_LanMountainPluginPackageVersion)' == ''">1.0.0
+ <_LanMountainPluginPackageOutputDirectory>$(LanMountainPluginPackageOutputDirectory)
+ <_LanMountainPluginPackageOutputDirectory Condition="'$(_LanMountainPluginPackageOutputDirectory)' == ''">$(MSBuildProjectDirectory)\
+ <_LanMountainPluginPackageFileName>$(LanMountainPluginPackageFileName)
+ <_LanMountainPluginPackageFileName Condition="'$(_LanMountainPluginPackageFileName)' == ''">$(_LanMountainPluginAssemblyName).$(_LanMountainPluginPackageVersion)$(LanMountainPluginPackageExtension)
+ <_LanMountainPluginPackagePath>$(LanMountainPluginPackagePath)
+ <_LanMountainPluginPackagePath Condition="'$(_LanMountainPluginPackagePath)' == ''">$(_LanMountainPluginPackageOutputDirectory)$(_LanMountainPluginPackageFileName)
+ <_LanMountainPluginManifestOutputPath>$(_LanMountainPluginBuildOutputDirectory)$(LanMountainPluginManifestFileName)
+ <_LanMountainPluginDepsPath>$(ProjectDepsFilePath)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/LanMountainDesktop.PluginTemplate/LanMountainDesktop.PluginTemplate.csproj b/LanMountainDesktop.PluginTemplate/LanMountainDesktop.PluginTemplate.csproj
new file mode 100644
index 0000000..328de1b
--- /dev/null
+++ b/LanMountainDesktop.PluginTemplate/LanMountainDesktop.PluginTemplate.csproj
@@ -0,0 +1,25 @@
+
+
+ net10.0
+ $(NoWarn);NU5128
+ false
+ LanMountainDesktop.PluginTemplate
+ 1.0.0
+ LanMountainDesktop
+ Official dotnet new template package for LanMountainDesktop plugins.
+ LanMountainDesktop;Plugin;Template;dotnet-new
+ Template
+ README.md
+ https://github.com/wwiinnddyy/LanMountainDesktop
+ git
+ false
+ true
+ true
+
+
+
+
+
+
+
+
diff --git a/LanMountainDesktop.PluginTemplate/README.md b/LanMountainDesktop.PluginTemplate/README.md
new file mode 100644
index 0000000..8a58ce2
--- /dev/null
+++ b/LanMountainDesktop.PluginTemplate/README.md
@@ -0,0 +1,17 @@
+# LanMountainDesktop.PluginTemplate
+
+Official `dotnet new` template package for LanMountainDesktop plugins.
+
+## Install
+
+```powershell
+dotnet new install LanMountainDesktop.PluginTemplate
+```
+
+## Create a plugin
+
+```powershell
+dotnet new lmd-plugin -n YourPluginName
+```
+
+The generated project references `LanMountainDesktop.PluginSdk` and produces a `.laapp` package automatically when built.
diff --git a/LanMountainDesktop.PluginTemplate/content/.template.config/template.json b/LanMountainDesktop.PluginTemplate/content/.template.config/template.json
new file mode 100644
index 0000000..936c3e4
--- /dev/null
+++ b/LanMountainDesktop.PluginTemplate/content/.template.config/template.json
@@ -0,0 +1,55 @@
+{
+ "$schema": "http://json.schemastore.org/template",
+ "author": "LanMountainDesktop",
+ "classifications": [
+ "LanMountainDesktop",
+ "Plugin",
+ "Desktop"
+ ],
+ "name": "LanMountainDesktop Plugin",
+ "identity": "LanMountainDesktop.PluginTemplate.CSharp",
+ "shortName": "lmd-plugin",
+ "sourceName": "LanMountainDesktop.PluginTemplate",
+ "preferNameDirectory": true,
+ "tags": {
+ "type": "project",
+ "language": "C#"
+ },
+ "symbols": {
+ "pluginId": {
+ "type": "parameter",
+ "datatype": "text",
+ "defaultValue": "LanMountainDesktop.PluginTemplate",
+ "description": "Plugin manifest id.",
+ "replaces": "__PLUGIN_ID__"
+ },
+ "pluginAuthor": {
+ "type": "parameter",
+ "datatype": "text",
+ "defaultValue": "Your Name",
+ "description": "Plugin author.",
+ "replaces": "__PLUGIN_AUTHOR__"
+ },
+ "pluginName": {
+ "type": "parameter",
+ "datatype": "text",
+ "defaultValue": "LanMountain Plugin Template",
+ "description": "Display name shown in plugin manifest.",
+ "replaces": "__PLUGIN_NAME__"
+ },
+ "pluginDescription": {
+ "type": "parameter",
+ "datatype": "text",
+ "defaultValue": "Plugin generated from the official LanMountainDesktop template.",
+ "description": "Plugin description shown in plugin manifest.",
+ "replaces": "__PLUGIN_DESCRIPTION__"
+ },
+ "pluginSdkVersion": {
+ "type": "parameter",
+ "datatype": "text",
+ "defaultValue": "4.0.0",
+ "description": "LanMountainDesktop.PluginSdk package version.",
+ "replaces": "__PLUGIN_SDK_VERSION__"
+ }
+ }
+}
diff --git a/LanMountainDesktop.PluginTemplate/content/LanMountainDesktop.PluginTemplate.csproj b/LanMountainDesktop.PluginTemplate/content/LanMountainDesktop.PluginTemplate.csproj
new file mode 100644
index 0000000..b763a85
--- /dev/null
+++ b/LanMountainDesktop.PluginTemplate/content/LanMountainDesktop.PluginTemplate.csproj
@@ -0,0 +1,19 @@
+
+
+ net10.0
+ enable
+ enable
+ 1.0.0
+ true
+ $(Version)
+
+
+
+
+
+
+
+
+
+
+
diff --git a/LanMountainDesktop.PluginTemplate/content/Localization/en-US.json b/LanMountainDesktop.PluginTemplate/content/Localization/en-US.json
new file mode 100644
index 0000000..2c63c08
--- /dev/null
+++ b/LanMountainDesktop.PluginTemplate/content/Localization/en-US.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/LanMountainDesktop.PluginTemplate/content/Localization/zh-CN.json b/LanMountainDesktop.PluginTemplate/content/Localization/zh-CN.json
new file mode 100644
index 0000000..2c63c08
--- /dev/null
+++ b/LanMountainDesktop.PluginTemplate/content/Localization/zh-CN.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/LanMountainDesktop.PluginTemplate/content/Plugin.cs b/LanMountainDesktop.PluginTemplate/content/Plugin.cs
new file mode 100644
index 0000000..fe100eb
--- /dev/null
+++ b/LanMountainDesktop.PluginTemplate/content/Plugin.cs
@@ -0,0 +1,15 @@
+using LanMountainDesktop.PluginSdk;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+
+namespace LanMountainDesktop.PluginTemplate;
+
+[PluginEntrance]
+public sealed class Plugin : PluginBase
+{
+ public override void Initialize(HostBuilderContext context, IServiceCollection services)
+ {
+ _ = context;
+ _ = services;
+ }
+}
diff --git a/LanMountainDesktop.PluginTemplate/content/README.md b/LanMountainDesktop.PluginTemplate/content/README.md
new file mode 100644
index 0000000..0a9bd45
--- /dev/null
+++ b/LanMountainDesktop.PluginTemplate/content/README.md
@@ -0,0 +1,24 @@
+# __PLUGIN_NAME__
+
+Official-style plugin scaffold generated for LanMountainDesktop.
+
+## Build
+
+```powershell
+dotnet build -c Release
+```
+
+`LanMountainDesktop.PluginSdk` build targets will generate:
+
+- plugin output files under `bin///`
+- a `.laapp` package in the project root
+
+## Manifest
+
+Update `plugin.json` fields as needed before release:
+
+- `id`
+- `name`
+- `description`
+- `author`
+- `version`
diff --git a/LanMountainDesktop.PluginTemplate/content/plugin.json b/LanMountainDesktop.PluginTemplate/content/plugin.json
new file mode 100644
index 0000000..5de5e7d
--- /dev/null
+++ b/LanMountainDesktop.PluginTemplate/content/plugin.json
@@ -0,0 +1,10 @@
+{
+ "id": "__PLUGIN_ID__",
+ "name": "__PLUGIN_NAME__",
+ "description": "__PLUGIN_DESCRIPTION__",
+ "author": "__PLUGIN_AUTHOR__",
+ "version": "1.0.0",
+ "apiVersion": "4.0.0",
+ "entranceAssembly": "LanMountainDesktop.PluginTemplate.dll",
+ "sharedContracts": []
+}
diff --git a/LanMountainDesktop.Shared.Contracts/LanMountainDesktop.Shared.Contracts.csproj b/LanMountainDesktop.Shared.Contracts/LanMountainDesktop.Shared.Contracts.csproj
index d23bea9..c44b5dd 100644
--- a/LanMountainDesktop.Shared.Contracts/LanMountainDesktop.Shared.Contracts.csproj
+++ b/LanMountainDesktop.Shared.Contracts/LanMountainDesktop.Shared.Contracts.csproj
@@ -3,8 +3,20 @@
net10.0
enable
enable
+ 1.0.0
+ LanMountainDesktop.Shared.Contracts
+ true
+ LanMountainDesktop
+ Shared contracts used by LanMountainDesktop host and plugins for cross-boundary communication.
+ LanMountainDesktop;Plugin;SharedContracts;Avalonia
+ README.md
+ https://github.com/wwiinnddyy/LanMountainDesktop
+ git
+
+
+
diff --git a/LanMountainDesktop.Shared.Contracts/README.md b/LanMountainDesktop.Shared.Contracts/README.md
new file mode 100644
index 0000000..d2f94b3
--- /dev/null
+++ b/LanMountainDesktop.Shared.Contracts/README.md
@@ -0,0 +1,16 @@
+# LanMountainDesktop.Shared.Contracts
+
+Shared contracts package for LanMountainDesktop host and plugin ecosystems.
+
+## Includes
+
+- cross-boundary records used by host/runtime and plugins
+- contract types intended for stable shared communication
+
+## Usage
+
+```xml
+
+
+
+```
diff --git a/LanMountainDesktop.slnx b/LanMountainDesktop.slnx
index 61bb691..acef7e8 100644
--- a/LanMountainDesktop.slnx
+++ b/LanMountainDesktop.slnx
@@ -6,6 +6,7 @@
+
diff --git a/PRODUCT_BRIEF.md b/PRODUCT_BRIEF.md
index cb33428..4f91e17 100644
--- a/PRODUCT_BRIEF.md
+++ b/PRODUCT_BRIEF.md
@@ -4,7 +4,7 @@
- **学生群体**:大学生、研究生、备考人员
- **办公用户**:白领、远程工作者
-- **效率爱好者**:工具控、桌面美化爱好者
+- **桌面美化爱好者**:追求个性化桌面布局与视觉体验的用户
## 2. 使用场景
@@ -32,60 +32,15 @@
| 信息分散,需打开多个应用 | 桌面聚合展示天气、日历、新闻等信息 |
| 桌面单调,缺乏个性化 | 丰富的组件和主题自由定制 |
| 学习管理不便 | 课程表、自习监测专为学生设计 |
+| 功能单一,需安装多个独立应用 | 一个应用整合考试看板、噪音监测等多种功能 |
| 功能无法满足个性需求 | 插件系统支持无限扩展 |
-## 5. 竞品对比分析
+## 5. 产品进度
-### 5.1 产品定位差异
-
-| 产品 | 定位 | 主要场景 | 目标用户 |
-|-----|------|---------|---------|
-| **阑山桌面** | 个人桌面信息聚合与效率工具 | 个人学习、办公、信息获取 | 学生、办公人员、个人用户 |
-| **希沃桌面** | 教室大屏教学系统 | 课堂教学、多媒体展示 | 中小学教师、学校 |
-| **鸿合鸿U** | 交互式教学系统 | 课堂授课、教学管理 | 教师、教育机构 |
-| **鸿合 Lesson+** | AI 备授课软件 | 备课、授课、互动、评价 | 教师 |
-| **Classworks** | 教学资源与课堂管理 | 课堂互动、学情分析 | 教师、学校 |
-
-### 5.2 功能对比
-
-| 功能维度 | 阑山桌面 | 希沃/鸿合系列 |
-|---------|---------|--------------|
-| **核心功能** | 桌面组件、信息展示、效率工具 | 教学白板、课件展示、课堂互动 |
-| **组件/工具** | 时钟、天气、日历、新闻、课程表 | 学科工具、白板批注、思维导图 |
-| **插件扩展** | ✅ 支持第三方插件 | ❌ 封闭系统 |
-| **跨平台** | ✅ Windows/Linux/macOS | ❌ 主要 Windows |
-| **硬件依赖** | 无,纯软件 | 需配合交互大屏/白板 |
-| **AI 功能** | 暂无 | 鸿合 Lesson+ 集成教学大模型 |
-| **课堂互动** | 不支持 | 多屏互动、学生端连接 |
-| **教学资源** | 无内置 | 丰富的学科资源库 |
-| **使用场景** | 个人电脑桌面 | 教室大屏教学 |
-| **部署方式** | 个人安装 | 学校/机构批量部署 |
-
-### 5.3 竞争优势
-
-| 优势 | 说明 |
-|-----|------|
-| **个人用户导向** | 专注个人效率,无需专用硬件 |
-| **开放生态** | 插件系统支持功能无限扩展 |
-| **跨平台支持** | 支持三大主流操作系统 |
-| **轻量灵活** | 纯软件方案,部署成本低 |
-| **隐私保护** | 本地数据存储,不上传个人信息 |
-
-### 5.4 竞争劣势
-
-| 劣势 | 说明 |
-|-----|------|
-| **非教学专用** | 缺乏专业教学工具和资源 |
-| **无课堂互动** | 不支持学生端连接和课堂互动 |
-| **无 AI 功能** | 暂不具备 AI 辅助教学能力 |
-| **品牌认知** | 教育市场知名度低于希沃/鸿合 |
-
-## 6. 产品进度
-
-- **当前版本**:v1.0.0(插件 API 3.0.0)
-- **开发状态**:核心功能已完成,进入优化迭代阶段
+- **当前版本**:v0.7.0(插件 API 3.0.0)
+- **开发状态**:核心功能开发中,预计 v1.0 正式发布
- **用户统计**:通过 PostHog 收集匿名数据(具体数据需后台查看)
---
-**一句话总结**:阑山桌面是一款面向个人用户的可定制桌面工具,与希沃、鸿合等教育大屏系统不同,专注个人学习办公场景,通过组件化设计和插件生态提供轻量、开放、跨平台的桌面信息聚合方案。
+**一句话总结**:阑山桌面是一款面向个人用户的可定制桌面工具,专注个人学习办公场景,通过组件化设计和插件生态提供轻量、开放、跨平台的桌面信息聚合方案。
diff --git a/README.md b/README.md
index 8be2891..89d8176 100644
--- a/README.md
+++ b/README.md
@@ -35,6 +35,14 @@ This repository does not own:
- Appearance model: `IPluginAppearanceContext`, `PluginAppearanceSnapshot`, `PluginCornerRadiusTokens`, `PluginCornerRadiusPreset`
- Component registration model: `AddPluginDesktopComponent(PluginDesktopComponentOptions options)`
+## Plugin Package Surfaces
+
+- `LanMountainDesktop.PluginSdk`: official plugin SDK package (includes `buildTransitive` default `.laapp` packaging targets)
+- `LanMountainDesktop.Shared.Contracts`: shared contract package for host/plugin boundaries
+- `LanMountainDesktop.PluginTemplate`: official `dotnet new` template package (`shortName`: `lmd-plugin`)
+
+Use `scripts/Pack-PluginPackages.ps1` to generate local-feed packages for CI or workspace integration tests.
+
## Workspace Market Resolution
For local market debugging, the host resolves workspace files from the sibling repository path (`..\\LanAirApp`) instead of reading the in-repo mirror folder.
diff --git a/scripts/Pack-PluginPackages.ps1 b/scripts/Pack-PluginPackages.ps1
new file mode 100644
index 0000000..906a690
--- /dev/null
+++ b/scripts/Pack-PluginPackages.ps1
@@ -0,0 +1,57 @@
+[CmdletBinding()]
+param(
+ [string]$OutputPath,
+ [string]$Configuration = "Release",
+ [string]$Version,
+ [string]$NuGetPackagesPath
+)
+
+Set-StrictMode -Version Latest
+$ErrorActionPreference = "Stop"
+
+$repoRoot = Split-Path -Parent $PSScriptRoot
+if ([string]::IsNullOrWhiteSpace($OutputPath)) {
+ $OutputPath = Join-Path $repoRoot "artifacts\nuget"
+}
+if ([string]::IsNullOrWhiteSpace($NuGetPackagesPath)) {
+ $NuGetPackagesPath = Join-Path $repoRoot ".nuget\packages"
+}
+
+$resolvedOutputPath = [System.IO.Path]::GetFullPath($OutputPath)
+New-Item -ItemType Directory -Force -Path $resolvedOutputPath | Out-Null
+$resolvedNuGetPackagesPath = [System.IO.Path]::GetFullPath($NuGetPackagesPath)
+New-Item -ItemType Directory -Force -Path $resolvedNuGetPackagesPath | Out-Null
+$env:NUGET_PACKAGES = $resolvedNuGetPackagesPath
+
+$projects = @(
+ "LanMountainDesktop.Shared.Contracts\LanMountainDesktop.Shared.Contracts.csproj",
+ "LanMountainDesktop.PluginSdk\LanMountainDesktop.PluginSdk.csproj",
+ "LanMountainDesktop.PluginTemplate\LanMountainDesktop.PluginTemplate.csproj"
+)
+
+$versionArgs = @()
+if (-not [string]::IsNullOrWhiteSpace($Version)) {
+ $versionArgs += "-p:Version=$Version"
+}
+
+foreach ($project in $projects) {
+ $projectPath = Join-Path $repoRoot $project
+ if (-not (Test-Path -Path $projectPath)) {
+ throw "Project '$projectPath' was not found."
+ }
+
+ Write-Host "Packing $project..."
+ $args = @(
+ "pack",
+ $projectPath,
+ "-c", $Configuration,
+ "-o", $resolvedOutputPath
+ ) + $versionArgs
+
+ & dotnet @args
+ if ($LASTEXITCODE -ne 0) {
+ throw "dotnet pack failed for '$projectPath' with exit code $LASTEXITCODE."
+ }
+}
+
+Write-Host "Plugin packages generated to '$resolvedOutputPath'."