diff --git a/KitX Contracts/KitX.Contract.CSharp/TriggerHelper.cs b/KitX Contracts/KitX.Contract.CSharp/TriggerHelper.cs
new file mode 100644
index 0000000..7854215
--- /dev/null
+++ b/KitX Contracts/KitX.Contract.CSharp/TriggerHelper.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Text.Json;
+using KitX.Shared.CSharp.WebCommand;
+using KitX.Shared.CSharp.WebCommand.Infos;
+
+namespace KitX.Contract.CSharp;
+
+///
+/// 插件触发器辅助工具。插件通过此类发送触发信号到 Dashboard。
+/// 触发器是纯信号,不携带业务数据。工作流被触发后通过调用插件函数获取数据。
+///
+public static class TriggerHelper
+{
+ private static readonly JsonSerializerOptions _options = new()
+ {
+ WriteIndented = false,
+ IncludeFields = true,
+ PropertyNameCaseInsensitive = true,
+ };
+
+ ///
+ /// 触发一个信号事件
+ ///
+ /// SetSendCommandAction 提供的发送回调
+ /// 触发器名称
+ public static void FireTrigger(Action? sendAction, string triggerName)
+ {
+ if (sendAction is null) return;
+
+ var request = new Request
+ {
+ Type = RequestTypes.Command,
+ Version = RequestVersions.V1,
+ Content = JsonSerializer.Serialize(new Command
+ {
+ Request = CommandRequestInfo.TriggerFired,
+ Tags = new Dictionary { { "TriggerName", triggerName } }
+ }, _options)
+ };
+
+ sendAction.Invoke(request);
+ }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Activity/IActivityService.cs b/KitX Core Contracts/KitX.Core.Contract/Activity/IActivityService.cs
new file mode 100644
index 0000000..fae97e4
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Activity/IActivityService.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Threading.Tasks;
+
+namespace KitX.Core.Contract.Activity;
+
+///
+/// Activity management service interface
+///
+public interface IActivityService
+{
+ ///
+ /// Records app start event
+ ///
+ void RecordAppStart();
+
+ ///
+ /// Records app exit event
+ ///
+ void RecordAppExit();
+
+ ///
+ /// Records an activity
+ ///
+ /// The activity type
+ /// Optional details
+ void RecordActivity(string type, Dictionary? details = null);
+
+ ///
+ /// Gets activities
+ ///
+ /// Optional start date
+ /// Optional end date
+ /// Maximum number of activities to return
+ /// List of activities
+ IList GetActivities(DateTime? startDate = null, DateTime? endDate = null, int limit = 100);
+
+ ///
+ /// Gets activity statistics
+ ///
+ /// Start date
+ /// End date
+ /// Activity statistics
+ IActivityStatistics GetStatistics(DateTime startDate, DateTime endDate);
+
+ ///
+ /// Event raised when activities are updated
+ ///
+ event EventHandler? ActivitiesUpdated;
+}
+
+///
+/// Activity interface
+///
+public interface IActivity
+{
+ ///
+ /// Gets the activity ID
+ ///
+ string Id { get; }
+
+ ///
+ /// Gets the activity type
+ ///
+ string Type { get; }
+
+ ///
+ /// Gets the timestamp
+ ///
+ DateTime Timestamp { get; }
+
+ ///
+ /// Gets the details
+ ///
+ Dictionary Details { get; }
+}
+
+///
+/// Activity statistics interface
+///
+public interface IActivityStatistics
+{
+ ///
+ /// Gets the total number of activities
+ ///
+ int TotalActivities { get; }
+
+ ///
+ /// Gets the activities grouped by type
+ ///
+ Dictionary ActivitiesByType { get; }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Announcement/IAnnouncementService.cs b/KitX Core Contracts/KitX.Core.Contract/Announcement/IAnnouncementService.cs
new file mode 100644
index 0000000..ec5ff4c
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Announcement/IAnnouncementService.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Threading.Tasks;
+using KitX.Core.Contract.Configuration;
+
+namespace KitX.Core.Contract.Announcement;
+
+///
+/// Announcement service interface
+///
+public interface IAnnouncementService
+{
+ ///
+ /// Gets the announcement configuration
+ ///
+ IAnnouncementConfig AnnouncementConfig { get; }
+
+ ///
+ /// Checks for new announcements
+ ///
+ /// List of new announcements
+ Task> CheckNewAnnouncementsAsync();
+
+ ///
+ /// Marks an announcement as read
+ ///
+ /// The announcement ID
+ void MarkAsRead(string announcementId);
+
+ ///
+ /// Gets all read announcement IDs
+ ///
+ /// List of read announcement IDs
+ IReadOnlyList GetReadAnnouncementIds();
+
+ ///
+ /// Saves the announcement configuration
+ ///
+ void SaveAnnouncementConfig();
+
+ ///
+ /// Event raised when new announcements are available
+ ///
+ event EventHandler? NewAnnouncementsAvailable;
+}
+
+///
+/// Announcement interface
+///
+public interface IAnnouncement
+{
+ ///
+ /// Gets the announcement ID
+ ///
+ string Id { get; }
+
+ ///
+ /// Gets the announcement title
+ ///
+ string Title { get; }
+
+ ///
+ /// Gets the announcement content
+ ///
+ string Content { get; }
+
+ ///
+ /// Gets the publish date
+ ///
+ DateTime PublishDate { get; }
+
+ ///
+ /// Gets the version
+ ///
+ string Version { get; }
+}
+
+///
+/// New announcements event arguments
+///
+public class NewAnnouncementsEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the announcements
+ ///
+ public IReadOnlyList Announcements { get; set; } = Array.Empty();
+
+ ///
+ /// Gets or sets announcements as dictionary (date -> content)
+ ///
+ public Dictionary? AnnouncementsDict { get; set; }
+}
+
+///
+/// Announcement error event arguments
+///
+public class AnnouncementErrorEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the error message
+ ///
+ public string ErrorMessage { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the stack trace
+ ///
+ public string StackTrace { get; set; } = string.Empty;
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/ConfigChangedEventArgs.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/ConfigChangedEventArgs.cs
new file mode 100644
index 0000000..9e05817
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/ConfigChangedEventArgs.cs
@@ -0,0 +1,29 @@
+using System;
+
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Configuration changed event arguments
+///
+public class ConfigChangedEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the configuration type (e.g., "App", "Plugins", "Security")
+ ///
+ public string ConfigType { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the property name that changed
+ ///
+ public string PropertyName { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the old value
+ ///
+ public object? OldValue { get; set; }
+
+ ///
+ /// Gets or sets the new value
+ ///
+ public object? NewValue { get; set; }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/IActivityConfig.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/IActivityConfig.cs
new file mode 100644
index 0000000..8c15a61
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/IActivityConfig.cs
@@ -0,0 +1,9 @@
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Activity configuration section
+///
+public interface IActivityConf
+{
+ int TotalRecorded { get; set; }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/IAnnouncementConfig.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/IAnnouncementConfig.cs
new file mode 100644
index 0000000..845ee4a
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/IAnnouncementConfig.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+
+namespace KitX.Core.Contract.Configuration;
+
+public interface IAnnouncementConfig
+{
+ ///
+ /// Gets or sets the list of accepted announcement IDs
+ ///
+ List Accepted { get; set; }
+
+ ///
+ /// Gets or sets the config file location
+ ///
+ string? ConfigFileLocation { get; set; }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/IAppConfig.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/IAppConfig.cs
new file mode 100644
index 0000000..7dc51f5
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/IAppConfig.cs
@@ -0,0 +1,68 @@
+using System.Collections.Generic;
+
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Application configuration interface (complete structure)
+///
+public interface IAppConfig
+{
+ ///
+ /// Gets or sets the application configuration
+ ///
+ IAppConf App { get; set; }
+
+ ///
+ /// Gets or sets the windows configuration
+ ///
+ IWindowsConf Windows { get; set; }
+
+ ///
+ /// Gets or sets the pages configuration
+ ///
+ IPagesConf Pages { get; set; }
+
+ ///
+ /// Gets or sets the web configuration
+ ///
+ IWebConf Web { get; set; }
+
+ ///
+ /// Gets or sets the log configuration
+ ///
+ ILogConf Log { get; set; }
+
+ ///
+ /// Gets or sets the IO configuration
+ ///
+ IIOConf IO { get; set; }
+
+ ///
+ /// Gets or sets the activity configuration
+ ///
+ IActivityConf Activity { get; set; }
+
+ ///
+ /// Gets or sets the loaders configuration
+ ///
+ ILoadersConf Loaders { get; set; }
+}
+
+///
+/// Application configuration section
+///
+public interface IAppConf
+{
+ string IconFileName { get; set; }
+ string CoverIconFileName { get; set; }
+ string AppLanguage { get; set; }
+ string Theme { get; set; }
+ string ThemeColor { get; set; }
+ Dictionary SurpportLanguages { get; set; }
+ string LocalPluginsFileFolder { get; set; }
+ string LocalPluginsDataFolder { get; set; }
+ bool DeveloperSetting { get; set; }
+ bool ShowAnnouncementWhenStart { get; set; }
+ ulong RanTime { get; set; }
+ int LastBreakAfterExit { get; set; }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/IConfigLoader.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/IConfigLoader.cs
new file mode 100644
index 0000000..8f6d570
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/IConfigLoader.cs
@@ -0,0 +1,21 @@
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Loads configuration from files
+///
+public interface IConfigLoader
+{
+ ///
+ /// Loads a config file from the specified location
+ ///
+ /// Config type
+ /// Directory path
+ /// File name
+ /// The loaded config or default
+ T Load(string location, string fileName) where T : class, new();
+
+ ///
+ /// Loads SecurityConfig with special handling
+ ///
+ ISecurityConfig LoadSecurityConfig(string location);
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/IConfigSaver.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/IConfigSaver.cs
new file mode 100644
index 0000000..e6b8df7
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/IConfigSaver.cs
@@ -0,0 +1,16 @@
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Saves configuration to files
+///
+public interface IConfigSaver
+{
+ ///
+ /// Saves a config to the specified location
+ ///
+ /// Config type
+ /// Config to save
+ /// Directory path
+ /// File name
+ void Save(T config, string location, string fileName) where T : class;
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/IConfigService.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/IConfigService.cs
new file mode 100644
index 0000000..4c15a2a
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/IConfigService.cs
@@ -0,0 +1,44 @@
+using System;
+
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Configuration management service interface
+///
+public interface IConfigService
+{
+ ///
+ /// Gets the application configuration
+ ///
+ IAppConfig AppConfig { get; }
+
+ ///
+ /// Gets the plugins configuration
+ ///
+ IPluginsConfig PluginsConfig { get; }
+
+ ///
+ /// Gets the security configuration
+ ///
+ ISecurityConfig SecurityConfig { get; }
+
+ ///
+ /// Loads all configurations from files
+ ///
+ void Load();
+
+ ///
+ /// Saves all configurations to files
+ ///
+ void SaveAll();
+
+ ///
+ /// Reloads all configurations from files
+ ///
+ void Reload();
+
+ ///
+ /// Event raised when configuration changes
+ ///
+ event EventHandler? ConfigChanged;
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/IConfigWithMetadata.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/IConfigWithMetadata.cs
new file mode 100644
index 0000000..b43f4f3
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/IConfigWithMetadata.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Interface for configurations with metadata fields
+///
+public interface IConfigWithMetadata
+{
+ ///
+ /// Gets or sets the configuration file location
+ ///
+ string? ConfigFileLocation { get; set; }
+
+ ///
+ /// Gets or sets the configuration file watcher name
+ ///
+ string? ConfigFileWatcherName { get; set; }
+
+ ///
+ /// Gets or sets the configuration generated time
+ ///
+ DateTime? ConfigGeneratedTime { get; set; }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/IIOConfig.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/IIOConfig.cs
new file mode 100644
index 0000000..bf766f8
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/IIOConfig.cs
@@ -0,0 +1,10 @@
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// IO configuration section
+///
+public interface IIOConf
+{
+ int UpdatingCheckPerThreadFilesCount { get; set; }
+ int OperatingSystemVersionUpdateInterval { get; set; }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/ILoadersConfig.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/ILoadersConfig.cs
new file mode 100644
index 0000000..c1ba09b
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/ILoadersConfig.cs
@@ -0,0 +1,9 @@
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Loaders configuration section
+///
+public interface ILoadersConf
+{
+ string InstallPath { get; set; }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/ILogConfig.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/ILogConfig.cs
new file mode 100644
index 0000000..4dbb731
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/ILogConfig.cs
@@ -0,0 +1,16 @@
+using Serilog.Events;
+
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Log configuration section
+///
+public interface ILogConf
+{
+ long LogFileSingleMaxSize { get; set; }
+ string LogFilePath { get; set; }
+ string LogTemplate { get; set; }
+ int LogFileMaxCount { get; set; }
+ int LogFileFlushInterval { get; set; }
+ public LogEventLevel LogLevel { get; set; }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/IPagesConfig.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/IPagesConfig.cs
new file mode 100644
index 0000000..39dff37
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/IPagesConfig.cs
@@ -0,0 +1,42 @@
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Pages configuration section
+///
+public interface IPagesConf
+{
+ IHomePageConf Home { get; set; }
+ object? Device { get; set; }
+ object? Market { get; set; }
+ ISettingsPageConf Settings { get; set; }
+}
+
+///
+/// Home page configuration
+///
+public interface IHomePageConf
+{
+ NavigationViewPaneDisplayMode NavigationViewPaneDisplayMode { get; set; }
+ string SelectedViewName { get; set; }
+ bool IsNavigationViewPaneOpened { get; set; }
+ bool UseAreaExpanded { get; set; }
+}
+
+///
+/// Settings page configuration
+///
+public interface ISettingsPageConf
+{
+ NavigationViewPaneDisplayMode NavigationViewPaneDisplayMode { get; set; }
+ string SelectedViewName { get; set; }
+ bool PaletteAreaExpanded { get; set; }
+ bool WebRelatedAreaExpanded { get; set; }
+ bool WebRelatedAreaOfNetworkInterfacesExpanded { get; set; }
+ bool LogRelatedAreaExpanded { get; set; }
+ bool UpdateRelatedAreaExpanded { get; set; }
+ bool AboutAreaExpanded { get; set; }
+ bool AuthorsAreaExpanded { get; set; }
+ bool LinksAreaExpanded { get; set; }
+ bool ThirdPartyLicensesAreaExpanded { get; set; }
+ bool IsNavigationViewPaneOpened { get; set; }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/IPluginsConfig.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/IPluginsConfig.cs
new file mode 100644
index 0000000..92f9c2e
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/IPluginsConfig.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using KitX.Shared.CSharp.Device;
+using KitX.Shared.CSharp.Loader;
+using KitX.Shared.CSharp.Plugin;
+
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Plugins configuration interface
+///
+public interface IPluginsConfig
+{
+ ///
+ /// Gets or sets the list of plugin installations
+ ///
+ IList Plugins { get; set; }
+}
+
+///
+/// Plugin installation interface
+///
+public interface IPluginInstallation
+{
+ ///
+ /// Gets the unique identifier for this plugin installation
+ ///
+ Guid Id { get; }
+
+ ///
+ /// Gets the installation path
+ ///
+ string? InstallPath { get; }
+
+ ///
+ /// Gets or sets the plugin information
+ ///
+ PluginInfo? PluginInfo { get; set; }
+
+ ///
+ /// Gets or sets the loader information
+ ///
+ LoaderInfo? LoaderInfo { get; set; }
+
+ ///
+ /// Gets or sets the list of installed devices
+ ///
+ IList InstalledDevices { get; set; }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/ISecurityConfig.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/ISecurityConfig.cs
new file mode 100644
index 0000000..c100ce7
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/ISecurityConfig.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using KitX.Shared.CSharp.Device;
+
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Security configuration interface
+///
+public interface ISecurityConfig
+{
+ ///
+ /// Gets or sets the device keys list
+ ///
+ IList DeviceKeys { get; set; }
+}
+
+///
+/// Device key interface
+///
+public interface IDeviceKey
+{
+ ///
+ /// Gets the device locator
+ ///
+ DeviceLocator Device { get; }
+
+ ///
+ /// Gets the RSA public key in PEM format
+ ///
+ string? RsaPublicKeyPem { get; }
+
+ ///
+ /// Gets the MAC address
+ ///
+ string MacAddress { get; }
+
+ ///
+ /// Gets the device name
+ ///
+ string DeviceName { get; }
+
+ ///
+ /// Gets the public key
+ ///
+ string PublicKey { get; }
+
+ ///
+ /// Gets the time when the key was added
+ ///
+ DateTime AddedAt { get; }
+}
\ No newline at end of file
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/IWebConfig.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/IWebConfig.cs
new file mode 100644
index 0000000..ceb0887
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/IWebConfig.cs
@@ -0,0 +1,31 @@
+using System.Collections.Generic;
+
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Web configuration section
+///
+public interface IWebConf
+{
+ double DelayStartSeconds { get; set; }
+ string ApiServer { get; set; }
+ string ApiPath { get; set; }
+ int DevicesViewRefreshDelay { get; set; }
+ List? AcceptedNetworkInterfaces { get; set; }
+ int? UserSpecifiedDevicesServerPort { get; set; }
+ int? UserSpecifiedPluginsServerPort { get; set; }
+ int UdpPortSend { get; set; }
+ int UdpPortReceive { get; set; }
+ int UdpSendFrequency { get; set; }
+ string UdpBroadcastAddress { get; set; }
+ string IPFilter { get; set; }
+ int SocketBufferSize { get; set; }
+ int DeviceInfoTTLSeconds { get; set; }
+ bool DisableRemovingOfflineDeviceCard { get; set; }
+ string UpdateServer { get; set; }
+ string UpdatePath { get; set; }
+ string UpdateDownloadPath { get; set; }
+ string UpdateChannel { get; set; }
+ string UpdateSource { get; set; }
+ int DebugServicesServerPort { get; set; }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/IWindowsConfig.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/IWindowsConfig.cs
new file mode 100644
index 0000000..7d05b26
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/IWindowsConfig.cs
@@ -0,0 +1,41 @@
+using System.Collections.Generic;
+using Common.BasicHelper.Graphics.Screen;
+
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Windows configuration section
+///
+public interface IWindowsConf
+{
+ IMainWindowConf MainWindow { get; set; }
+ IAnnouncementWindowConf AnnouncementWindow { get; set; }
+}
+
+///
+/// Main window configuration
+///
+public interface IMainWindowConf
+{
+ Resolution Size { get; set; }
+ Distances Location { get; set; }
+ WindowState WindowState { get; set; }
+ bool IsHidden { get; set; }
+ Dictionary Tags { get; set; }
+ bool EnabledMica { get; set; }
+ int GreetingTextCount_Morning { get; set; }
+ int GreetingTextCount_Noon { get; set; }
+ int GreetingTextCount_AfterNoon { get; set; }
+ int GreetingTextCount_Evening { get; set; }
+ int GreetingTextCount_Night { get; set; }
+ int GreetingUpdateInterval { get; set; }
+}
+
+///
+/// Announcement window configuration
+///
+public interface IAnnouncementWindowConf
+{
+ Resolution Size { get; set; }
+ Distances Location { get; set; }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/NavigationViewPaneDisplayMode.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/NavigationViewPaneDisplayMode.cs
new file mode 100644
index 0000000..605e73f
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/NavigationViewPaneDisplayMode.cs
@@ -0,0 +1,13 @@
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Navigation view pane display mode enum
+///
+public enum NavigationViewPaneDisplayMode
+{
+ Auto = 0,
+ Left = 1,
+ Top = 2,
+ LeftCompact = 3,
+ LeftMinimal = 4
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Configuration/WindowState.cs b/KitX Core Contracts/KitX.Core.Contract/Configuration/WindowState.cs
new file mode 100644
index 0000000..8ffc493
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Configuration/WindowState.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace KitX.Core.Contract.Configuration;
+
+///
+/// Window state enumeration (mirrors Avalonia.WindowState)
+///
+public enum WindowState
+{
+ Normal,
+ Minimized,
+ Maximized,
+ FullScreen,
+ NonInteractive
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Device/IDeviceService.cs b/KitX Core Contracts/KitX.Core.Contract/Device/IDeviceService.cs
new file mode 100644
index 0000000..790c82c
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Device/IDeviceService.cs
@@ -0,0 +1,265 @@
+using System;
+using System.ComponentModel;
+using System.Net.Http;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+using KitX.Shared.CSharp.Device;
+
+namespace KitX.Core.Contract.Device;
+
+///
+/// Device management service interface
+///
+public interface IDeviceService
+{
+ ///
+ /// Gets the discovered devices list
+ ///
+ IReadOnlyList DiscoveredDevices { get; }
+
+ ///
+ /// Gets the authorized devices list
+ ///
+ IReadOnlyList AuthorizedDevices { get; }
+
+ ///
+ /// Gets the self device information
+ ///
+ DeviceInfo SelfDeviceInfo { get; }
+
+ ///
+ /// Gets a value indicating whether this device is the main device
+ ///
+ bool IsMainDevice { get; }
+
+ ///
+ /// Authorizes a device
+ ///
+ /// The device ID
+ /// The device key
+ /// True if authorization was successful
+ Task AuthorizeDeviceAsync(string deviceId, string deviceKey);
+
+ ///
+ /// Unauthorizes a device
+ ///
+ /// The device ID
+ /// True if unauthorization was successful
+ Task UnauthorizeDeviceAsync(string deviceId);
+
+ ///
+ /// Connects to a device
+ ///
+ /// The device ID
+ /// True if connection was successful
+ Task ConnectToDeviceAsync(string deviceId);
+
+ ///
+ /// Event raised when a device is discovered
+ ///
+ event EventHandler? DeviceDiscovered;
+
+ ///
+ /// Event raised when a device goes offline
+ ///
+ event EventHandler? DeviceOffline;
+
+ ///
+ /// Event raised when the main device changes
+ ///
+ event EventHandler? MainDeviceChanged;
+}
+
+///
+/// Device discovery service interface
+///
+public interface IDeviceDiscoveryService
+{
+ ///
+ /// Gets the default device information
+ ///
+ DeviceInfo DefaultDeviceInfo { get; }
+
+ ///
+ /// Gets the port the discovery service is running on
+ ///
+ int? Port { get; }
+
+ ///
+ /// Starts the device discovery service
+ ///
+ /// The service instance
+ IDeviceDiscoveryService Run();
+
+ ///
+ /// Stops the device discovery service
+ ///
+ void Stop();
+
+ ///
+ /// Event raised when a device is discovered
+ ///
+ event EventHandler? DeviceDiscovered;
+
+ ///
+ /// Event raised when a device goes offline
+ ///
+ event EventHandler? DeviceOffline;
+}
+
+///
+/// Device server interface for HTTP API
+///
+public interface IDeviceServer
+{
+ ///
+ /// Gets the port the server is running on
+ ///
+ int? Port { get; }
+
+ ///
+ /// Starts the device server
+ ///
+ /// The server instance
+ IDeviceServer Run();
+
+ ///
+ /// Stops the device server
+ ///
+ void Stop();
+
+ ///
+ /// Checks if a device is signed in
+ ///
+ /// The device locator
+ /// True if the device is signed in
+ bool IsDeviceSignedIn(KitX.Shared.CSharp.Device.DeviceLocator locator);
+
+ ///
+ /// Gets the signed device token for a device locator
+ ///
+ /// The device locator
+ /// The token or null if not found
+ string? GetDeviceToken(KitX.Shared.CSharp.Device.DeviceLocator locator);
+
+ ///
+ /// Gets all signed-in device locators
+ ///
+ /// Read-only list of signed-in device locators
+ System.Collections.Generic.IReadOnlyList GetSignedInDevices();
+}
+
+///
+/// Devices organizer interface
+///
+public interface IDevicesOrganizer
+{
+ ///
+ /// Updates the source and adds device cards
+ ///
+ /// The device info
+ void UpdateSourceAndAddCards(DeviceInfo deviceInfo);
+
+ ///
+ /// Event raised when a device is discovered
+ ///
+ event EventHandler? DeviceDiscovered;
+
+ ///
+ /// Event raised when a device goes offline
+ ///
+ event EventHandler? DeviceOffline;
+}
+
+///
+/// Device case interface
+///
+public interface IDeviceCase
+{
+ ///
+ /// Gets or sets the device information
+ ///
+ DeviceInfo DeviceInfo { get; set; }
+
+ ///
+ /// Gets a value indicating whether the device is authorized
+ ///
+ bool IsAuthorized { get; }
+
+ ///
+ /// Gets a value indicating whether this is the main device
+ ///
+ bool IsMainDevice { get; }
+
+ ///
+ /// Gets a value indicating whether the device is online
+ ///
+ bool IsOnline { get; }
+
+ ///
+ /// Gets the last seen time
+ ///
+ DateTime LastSeen { get; }
+}
+
+///
+/// Device discovered event arguments
+///
+public class DeviceDiscoveredEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the device information
+ ///
+ public DeviceInfo? DeviceInfo { get; set; }
+}
+
+///
+/// Device offline event arguments
+///
+public class DeviceOfflineEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the device ID
+ ///
+ public string DeviceId { get; set; } = string.Empty;
+}
+
+///
+/// Main device changed event arguments
+///
+public class MainDeviceChangedEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the old main device ID
+ ///
+ public string OldMainDeviceId { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the new main device ID
+ ///
+ public string NewMainDeviceId { get; set; } = string.Empty;
+}
+
+///
+/// Device HTTP client interface — sends requests to remote DevicesServer instances.
+/// Used for cross-device plugin invocation via the /Api/V1/Plugin/Invoke endpoint.
+/// (Moved to Contract so the Workflow library can depend on the abstraction without
+/// referencing KitX.Core.)
+///
+public interface IDeviceHttpClient
+{
+ ///
+ /// Invokes a plugin method on a remote device via HTTP POST to /Api/V1/Plugin/Invoke.
+ ///
+ /// Target device info (contains IPv4 and DevicesServerPort)
+ /// Valid session token for the target device
+ /// The Request object to send
+ /// Cancellation token
+ /// HTTP response from remote device, or null on network error
+ Task InvokePluginAsync(
+ DeviceInfo targetDevice,
+ string token,
+ KitX.Shared.CSharp.WebCommand.Request request,
+ CancellationToken ct = default);
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Device/ServerStatus.cs b/KitX Core Contracts/KitX.Core.Contract/Device/ServerStatus.cs
new file mode 100644
index 0000000..c41bda0
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Device/ServerStatus.cs
@@ -0,0 +1,13 @@
+namespace KitX.Core.Contract.Device;
+
+///
+/// Server status enumeration
+///
+public enum ServerStatus
+{
+ Pending,
+ Starting,
+ Running,
+ Stopping,
+ Errored
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Event/IEventService.cs b/KitX Core Contracts/KitX.Core.Contract/Event/IEventService.cs
new file mode 100644
index 0000000..843b86a
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Event/IEventService.cs
@@ -0,0 +1,58 @@
+using System;
+using System.ComponentModel;
+
+namespace KitX.Core.Contract.Event;
+
+///
+/// Event service interface for global event bus
+///
+public interface IEventService
+{
+ ///
+ /// Subscribes to an event
+ ///
+ /// The event name
+ /// The event handler
+ void Subscribe(string eventName, EventHandler handler);
+
+ ///
+ /// Unsubscribes from an event
+ ///
+ /// The event name
+ /// The event handler
+ void Unsubscribe(string eventName, EventHandler handler);
+
+ ///
+ /// Publishes an event
+ ///
+ /// The event name
+ /// The event arguments
+ void Publish(string eventName, EventArgs args);
+
+ ///
+ /// Subscribes to a typed event
+ ///
+ /// The event args type
+ /// The event name
+ /// The event handler
+ void Subscribe(string eventName, EventHandler handler)
+ where TEventArgs : EventArgs;
+
+ ///
+ /// Unsubscribes from a typed event
+ ///
+ /// The event args type
+ /// The event name
+ /// The event handler
+ void Unsubscribe(string eventName, EventHandler handler)
+ where TEventArgs : EventArgs;
+
+ ///
+ /// Publishes a typed event
+ ///
+ /// The event args type
+ /// The event name
+ /// The event arguments
+ void Publish(string eventName, TEventArgs args)
+ where TEventArgs : EventArgs;
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Event/WorkflowEventArgs.cs b/KitX Core Contracts/KitX.Core.Contract/Event/WorkflowEventArgs.cs
new file mode 100644
index 0000000..cda2807
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Event/WorkflowEventArgs.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Collections.Generic;
+
+namespace KitX.Core.Contract.Event;
+
+///
+/// Event arguments for workflow rename events
+///
+public class WorkflowRenamedEventArgs : EventArgs
+{
+ ///
+ /// The workflow ID that was renamed
+ ///
+ public string WorkflowId { get; }
+
+ ///
+ /// The new name of the workflow
+ ///
+ public string NewName { get; }
+
+ public WorkflowRenamedEventArgs(string workflowId, string newName)
+ {
+ WorkflowId = workflowId;
+ NewName = newName;
+ }
+}
+
+///
+/// Event arguments for workflow data saved events
+///
+public class WorkflowSavedEventArgs : EventArgs
+{
+ ///
+ /// The workflow ID that was saved
+ ///
+ public string WorkflowId { get; }
+
+ ///
+ /// The workflow name at time of save
+ ///
+ public string WorkflowName { get; }
+
+ ///
+ /// The workflow description at time of save
+ ///
+ public string Description { get; }
+
+ ///
+ /// The workflow author at time of save
+ ///
+ public string Author { get; }
+
+ public WorkflowSavedEventArgs(string workflowId, string workflowName,
+ string description = "", string author = "")
+ {
+ WorkflowId = workflowId;
+ WorkflowName = workflowName;
+ Description = description;
+ Author = author;
+ }
+}
+
+///
+/// Event arguments for workflow execution result events
+///
+public class WorkflowExecutionResultEventArgs : EventArgs
+{
+ ///
+ /// The workflow ID that was executed
+ ///
+ public string WorkflowId { get; }
+
+ ///
+ /// Whether the execution succeeded
+ ///
+ public bool IsSuccess { get; }
+
+ ///
+ /// Error message if execution failed
+ ///
+ public string? ErrorMessage { get; }
+
+ ///
+ /// Lines of Print() output produced during execution (null if not captured).
+ /// Surfaced to the Debug activity log so users can see what the workflow printed
+ /// without opening the editor's output panel.
+ ///
+ public IReadOnlyList? Output { get; }
+
+ public WorkflowExecutionResultEventArgs(string workflowId, bool isSuccess,
+ string? errorMessage = null, IReadOnlyList? output = null)
+ {
+ WorkflowId = workflowId;
+ IsSuccess = isSuccess;
+ ErrorMessage = errorMessage;
+ Output = output;
+ }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Event/WorkflowEventNames.cs b/KitX Core Contracts/KitX.Core.Contract/Event/WorkflowEventNames.cs
new file mode 100644
index 0000000..b7985bb
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Event/WorkflowEventNames.cs
@@ -0,0 +1,21 @@
+namespace KitX.Core.Contract.Event;
+
+///
+/// Event-bus channel names shared between the Workflow library and its host
+/// (KitX.Core / KitX.Dashboard). Centralized here so the workflow library can
+/// publish/subscribe on the bus without referencing
+/// KitX.Core's own EventNames table.
+///
+public static class WorkflowEventNames
+{
+ ///
+ /// Plugin response event (carries a RequestId so callers can correlate
+ /// a fire-and-forget plugin invocation with its reply).
+ ///
+ public const string PluginResponse = "PluginResponse";
+
+ ///
+ /// Workflow execution result event (success or failure of a workflow run).
+ ///
+ public const string WorkflowExecutionResult = "WorkflowExecutionResult";
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Events/CommonEventArgs.cs b/KitX Core Contracts/KitX.Core.Contract/Events/CommonEventArgs.cs
new file mode 100644
index 0000000..2e70a4d
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Events/CommonEventArgs.cs
@@ -0,0 +1,42 @@
+using System;
+using System.ComponentModel;
+
+namespace KitX.Core.Contract.Events;
+
+///
+/// Base class for event arguments
+///
+public abstract class BaseEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the timestamp when the event occurred
+ ///
+ public DateTime Timestamp { get; set; } = DateTime.UtcNow;
+}
+
+///
+/// Generic event arguments for simple event data
+///
+public class GenericEventArgs : BaseEventArgs
+{
+ ///
+ /// Gets or sets the event data
+ ///
+ public object? Data { get; set; }
+}
+
+///
+/// Generic event arguments with type parameter
+///
+public class GenericEventArgs : BaseEventArgs
+{
+ ///
+ /// Gets or sets the event data
+ ///
+ public T? Data { get; set; }
+
+ ///
+ /// Gets or sets the event type
+ ///
+ public string? EventType { get; set; }
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/FileWatcher/IFileWatcherService.cs b/KitX Core Contracts/KitX.Core.Contract/FileWatcher/IFileWatcherService.cs
new file mode 100644
index 0000000..037bc27
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/FileWatcher/IFileWatcherService.cs
@@ -0,0 +1,28 @@
+using System.IO;
+using System.ComponentModel;
+
+namespace KitX.Core.Contract.FileWatcher;
+
+///
+/// File watcher service interface
+///
+public interface IFileWatcherService
+{
+ ///
+ /// Registers a file watcher
+ ///
+ /// The file path to watch
+ /// The callback when file changes
+ void RegisterWatcher(string filePath, FileSystemEventHandler onChanged);
+
+ ///
+ /// Unregisters a file watcher
+ ///
+ /// The file path to stop watching
+ void UnregisterWatcher(string filePath);
+
+ ///
+ /// Clears all file watchers
+ ///
+ void Clear();
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Hotkey/IKeyHookService.cs b/KitX Core Contracts/KitX.Core.Contract/Hotkey/IKeyHookService.cs
new file mode 100644
index 0000000..9e1dddb
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Hotkey/IKeyHookService.cs
@@ -0,0 +1,32 @@
+using System;
+
+namespace KitX.Core.Contract.Hotkey;
+
+///
+/// Key hook service interface for global hotkeys
+///
+public interface IKeyHookService
+{
+ ///
+ /// Starts the key hook
+ ///
+ void StartHook();
+
+ ///
+ /// Stops the key hook
+ ///
+ void StopHook();
+
+ ///
+ /// Registers a hotkey handler
+ ///
+ /// The keys sequence
+ /// The handler
+ void RegisterHotKeyHandler(string keysSequence, Action handler);
+
+ ///
+ /// Unregisters a hotkey handler
+ ///
+ /// The keys sequence
+ void UnregisterHotKeyHandler(string keysSequence);
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/KitX-Background-ani.png b/KitX Core Contracts/KitX.Core.Contract/KitX-Background-ani.png
new file mode 100644
index 0000000..7abdbc3
Binary files /dev/null and b/KitX Core Contracts/KitX.Core.Contract/KitX-Background-ani.png differ
diff --git a/KitX Core Contracts/KitX.Core.Contract/KitX.Core.Contract.csproj b/KitX Core Contracts/KitX.Core.Contract/KitX.Core.Contract.csproj
new file mode 100644
index 0000000..7a9a866
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/KitX.Core.Contract.csproj
@@ -0,0 +1,49 @@
+
+
+
+ net10.0
+ enable
+ True
+
+
+
+ $(Version)
+ $(Version)
+ 24.10.$([System.DateTime]::UtcNow.Date.Subtract($([System.DateTime]::Parse("2024-02-07"))).TotalDays).$([System.Math]::Floor($([System.DateTime]::UtcNow.TimeOfDay.TotalMinutes)))
+
+
+
+ KitX.Core.Contract.CSharp
+ Dynesshely
+ Crequency
+ Core service contracts for KitX Dashboard written in C#
+ AGPL-3.0-only
+ True
+ KitX-Background-ani.png
+ README.md
+ https://github.com/Crequency/KitX/
+ https://github.com/Crequency/KitX-Standard/
+
+
+
+
+ True
+ \
+
+
+ True
+ \
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/KitX Core Contracts/KitX.Core.Contract/Plugin/Events/PluginEventArgs.cs b/KitX Core Contracts/KitX.Core.Contract/Plugin/Events/PluginEventArgs.cs
new file mode 100644
index 0000000..068086b
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Plugin/Events/PluginEventArgs.cs
@@ -0,0 +1,122 @@
+using System;
+using KitX.Shared.CSharp.Plugin;
+
+namespace KitX.Core.Contract.Plugin.Events;
+
+///
+/// Plugin status changed event arguments
+///
+public class PluginStatusChangedEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the plugin ID
+ ///
+ public Guid PluginId { get; set; }
+
+ ///
+ /// Gets or sets the plugin name
+ ///
+ public string PluginName { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the old status
+ ///
+ public PluginStatus OldStatus { get; set; }
+
+ ///
+ /// Gets or sets the new status
+ ///
+ public PluginStatus NewStatus { get; set; }
+}
+
+///
+/// Plugin response event arguments
+///
+public class PluginResponseEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the request ID
+ ///
+ public string RequestId { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the response content
+ ///
+ public string Content { get; set; } = string.Empty;
+}
+
+///
+/// Plugin status report event arguments
+///
+public class PluginStatusReportEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the connection ID
+ ///
+ public string ConnectionId { get; set; } = string.Empty;
+
+ ///
+ /// Gets or sets the status message
+ ///
+ public string Status { get; set; } = string.Empty;
+}
+
+///
+/// Plugin registered event arguments
+///
+public class PluginRegisteredEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the plugin info
+ ///
+ public PluginInfo? PluginInfo { get; set; }
+}
+
+///
+/// Plugin unregistered event arguments
+///
+public class PluginUnregisteredEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the plugin info
+ ///
+ public PluginInfo? PluginInfo { get; set; }
+}
+
+///
+/// Plugin connected event arguments
+///
+public class PluginConnectedEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the connection ID
+ ///
+ public string? ConnectionId { get; set; }
+}
+
+///
+/// Plugin disconnected event arguments
+///
+public class PluginDisconnectedEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the connection ID
+ ///
+ public string? ConnectionId { get; set; }
+}
+
+///
+/// Plugin message received event arguments
+///
+public class PluginMessageReceivedEventArgs : EventArgs
+{
+ ///
+ /// Gets or sets the connection ID
+ ///
+ public string? ConnectionId { get; set; }
+
+ ///
+ /// Gets or sets the message
+ ///
+ public string? Message { get; set; }
+}
\ No newline at end of file
diff --git a/KitX Core Contracts/KitX.Core.Contract/Plugin/IPluginConnection.cs b/KitX Core Contracts/KitX.Core.Contract/Plugin/IPluginConnection.cs
new file mode 100644
index 0000000..d343993
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Plugin/IPluginConnection.cs
@@ -0,0 +1,48 @@
+using System;
+using KitX.Shared.CSharp.Plugin;
+using KitX.Core.Contract.Device;
+using CTask = System.Threading.Tasks.Task;
+
+namespace KitX.Core.Contract.Plugin;
+
+///
+/// Plugin connection interface
+///
+public interface IPluginConnection : IPluginConnector
+{
+ ///
+ /// Gets or sets the plugin info
+ ///
+ new PluginInfo? PluginInfo { get; set; }
+
+ ///
+ /// Gets the connection status
+ ///
+ ServerStatus Status { get; }
+
+ ///
+ /// Event raised when a message is received
+ ///
+ event EventHandler? MessageReceived;
+
+ ///
+ /// Event raised when connection is closed
+ ///
+ event EventHandler? Closed;
+
+ ///
+ /// Initializes the connection
+ ///
+ void Initialize();
+
+ ///
+ /// Sends a message
+ ///
+ /// The message to send
+ void Send(string message);
+
+ ///
+ /// Closes the connection
+ ///
+ CTask CloseAsync();
+}
diff --git a/KitX Core Contracts/KitX.Core.Contract/Plugin/IPluginConnector.cs b/KitX Core Contracts/KitX.Core.Contract/Plugin/IPluginConnector.cs
new file mode 100644
index 0000000..5f63eff
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Plugin/IPluginConnector.cs
@@ -0,0 +1,37 @@
+using System;
+using KitX.Shared.CSharp.Plugin;
+using KitX.Core.Contract.Plugin.Events;
+
+namespace KitX.Core.Contract.Plugin;
+
+///
+/// Plugin connector interface for managing individual plugin connections
+///
+public interface IPluginConnector
+{
+ ///
+ /// Gets the connection ID
+ ///
+ string? ConnectionId { get; }
+
+ ///
+ /// Gets the plugin info
+ ///
+ PluginInfo? PluginInfo { get; }
+
+ ///
+ /// Sends a request to the plugin
+ ///
+ /// The request to send
+ void Request(object request);
+
+ ///
+ /// Event raised when a plugin response is received
+ ///
+ event EventHandler? PluginResponse;
+
+ ///
+ /// Event raised when plugin reports status
+ ///
+ event EventHandler? StatusReport;
+}
\ No newline at end of file
diff --git a/KitX Core Contracts/KitX.Core.Contract/Plugin/IPluginServer.cs b/KitX Core Contracts/KitX.Core.Contract/Plugin/IPluginServer.cs
new file mode 100644
index 0000000..871277a
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Plugin/IPluginServer.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Collections.Generic;
+using KitX.Shared.CSharp.Plugin;
+using KitX.Core.Contract.Plugin.Events;
+
+namespace KitX.Core.Contract.Plugin;
+
+///
+/// Plugin server interface for managing plugin connections
+///
+public interface IPluginServer
+{
+ ///
+ /// Gets the port the server is running on
+ ///
+ int? Port { get; }
+
+ ///
+ /// Gets the list of currently connected plugins
+ ///
+ IReadOnlyList Connections { get; }
+
+ ///
+ /// Starts the plugin server
+ ///
+ /// The server instance
+ IPluginServer Run();
+
+ ///
+ /// Stops the plugin server
+ ///
+ void Stop();
+
+ ///
+ /// Finds a connector for a specific plugin
+ ///
+ /// The plugin info
+ /// The plugin connector or null if not found
+ IPluginConnector? FindConnector(PluginInfo pluginInfo);
+
+ ///
+ /// Finds a connection by connection ID
+ ///
+ /// The connection ID
+ /// The plugin connection or null if not found
+ IPluginConnection? FindConnection(string connectionId);
+
+ ///
+ /// Event raised when server port changes
+ ///
+ event EventHandler? PortChanged;
+
+ ///
+ /// Event raised when a plugin connects
+ ///
+ event EventHandler? PluginConnected;
+
+ ///
+ /// Event raised when a plugin disconnects
+ ///
+ event EventHandler? PluginDisconnected;
+
+ ///
+ /// Event raised when a plugin message is received
+ ///
+ event EventHandler? PluginMessageReceived;
+
+ ///
+ /// Event raised when a plugin registers with the server
+ ///
+ event EventHandler? PluginRegistered;
+
+ ///
+ /// Event raised when a plugin unregisters/disconnects from the server
+ ///
+ event EventHandler? PluginUnregistered;
+
+ ///
+ /// Event raised when a plugin sends a response (has RequestId)
+ ///
+ event EventHandler? PluginResponse;
+}
\ No newline at end of file
diff --git a/KitX Core Contracts/KitX.Core.Contract/Plugin/IPluginService.cs b/KitX Core Contracts/KitX.Core.Contract/Plugin/IPluginService.cs
new file mode 100644
index 0000000..495e5a2
--- /dev/null
+++ b/KitX Core Contracts/KitX.Core.Contract/Plugin/IPluginService.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using KitX.Core.Contract.Configuration;
+using KitX.Shared.CSharp.Plugin;
+using KitX.Core.Contract.Plugin.Events;
+
+namespace KitX.Core.Contract.Plugin;
+
+///
+/// Plugin management service interface
+///
+public interface IPluginService
+{
+ ///
+ /// Gets all installed plugins
+ ///
+ IReadOnlyList GetInstalledPlugins();
+
+ ///
+ /// Gets a plugin by its ID
+ ///
+ /// The plugin ID
+ /// The plugin installation or null if not found
+ IPluginInstallation? GetPlugin(Guid pluginId);
+
+ ///
+ /// Imports a plugin package (.kxp file)
+ ///
+ /// Path to the .kxp file
+ /// True if import was successful
+ Task ImportPluginAsync(string kxpFilePath);
+
+ ///
+ /// Removes a plugin
+ ///
+ /// The plugin ID
+ /// True if removal was successful
+ Task RemovePluginAsync(Guid pluginId);
+
+ ///
+ /// Starts a plugin
+ ///
+ /// The plugin ID
+ /// True if start was successful
+ Task StartPluginAsync(Guid pluginId);
+
+ ///
+ /// Stops a plugin
+ ///
+ /// The plugin ID
+ /// True if stop was successful
+ Task StopPluginAsync(Guid pluginId);
+
+ ///
+ /// Calls a plugin function
+ ///
+ /// The plugin ID
+ /// The function name
+ /// Optional parameters
+ /// The function result
+ Task