diff --git a/Dalamud/Plugin/DalamudPluginInterface.cs b/Dalamud/Plugin/DalamudPluginInterface.cs
index c443425f5..8d22db568 100644
--- a/Dalamud/Plugin/DalamudPluginInterface.cs
+++ b/Dalamud/Plugin/DalamudPluginInterface.cs
@@ -202,7 +202,8 @@ public sealed class DalamudPluginInterface : IDalamudPluginInterface, IDisposabl
///
/// Gets a list of installed plugins along with their current state.
///
- public IEnumerable InstalledPlugins => Service.Get().InstalledPlugins.Select(p => new InstalledPluginState(p.Name, p.Manifest.InternalName, p.IsLoaded, p.EffectiveVersion));
+ public IEnumerable InstalledPlugins =>
+ Service.Get().InstalledPlugins.Select(p => new ExposedPlugin(p));
///
/// Gets the internal implementation.
diff --git a/Dalamud/Plugin/IDalamudPluginInterface.cs b/Dalamud/Plugin/IDalamudPluginInterface.cs
index 227dbc9d3..7f660f3cd 100644
--- a/Dalamud/Plugin/IDalamudPluginInterface.cs
+++ b/Dalamud/Plugin/IDalamudPluginInterface.cs
@@ -155,7 +155,7 @@ public interface IDalamudPluginInterface
///
/// Gets a list of installed plugins along with their current state.
///
- IEnumerable InstalledPlugins { get; }
+ IEnumerable InstalledPlugins { get; }
///
/// Opens the with the plugin name set as search target.
diff --git a/Dalamud/Plugin/InstalledPluginState.cs b/Dalamud/Plugin/InstalledPluginState.cs
index 3cdd03956..f92cc0c2c 100644
--- a/Dalamud/Plugin/InstalledPluginState.cs
+++ b/Dalamud/Plugin/InstalledPluginState.cs
@@ -1,13 +1,94 @@
-using Dalamud.Utility;
+using Dalamud.Plugin.Internal.Types;
namespace Dalamud.Plugin;
///
-/// State of an installed plugin.
+/// Interface representing an installed plugin, to be exposed to other plugins.
///
-/// The name of the plugin.
-/// The internal name of the plugin.
-/// Whether or not the plugin is loaded.
-/// The version of the plugin.
-[Api10ToDo("Refactor into an interface, add wrappers for OpenMainUI and OpenConfigUI")]
-public record InstalledPluginState(string Name, string InternalName, bool IsLoaded, Version Version);
+public interface IExposedPlugin
+{
+ ///
+ /// Gets the name of the plugin.
+ ///
+ string Name { get; }
+
+ ///
+ /// Gets the internal name of the plugin.
+ ///
+ string InternalName { get; }
+
+ ///
+ /// Gets a value indicating whether the plugin is loaded.
+ ///
+ bool IsLoaded { get; }
+
+ ///
+ /// Gets the version of the plugin.
+ ///
+ Version Version { get; }
+
+ ///
+ /// Gets a value indicating whether the plugin has a main UI.
+ ///
+ public bool HasMainUi { get; }
+
+ ///
+ /// Gets a value indicating whether the plugin has a config UI.
+ ///
+ public bool HasConfigUi { get; }
+
+ ///
+ /// Opens the main UI of the plugin.
+ /// Throws if is false.
+ ///
+ public void OpenMainUi();
+
+ ///
+ /// Opens the config UI of the plugin.
+ /// Throws if is false.
+ ///
+ public void OpenConfigUi();
+}
+
+///
+/// Internal representation of an installed plugin, to be exposed to other plugins.
+///
+/// The plugin.
+internal sealed class ExposedPlugin(LocalPlugin plugin) : IExposedPlugin
+{
+ ///
+ public string Name => plugin.Name;
+
+ ///
+ public string InternalName => plugin.InternalName;
+
+ ///
+ public bool IsLoaded => plugin.IsLoaded;
+
+ ///
+ public Version Version => plugin.EffectiveVersion;
+
+ ///
+ public bool HasMainUi => plugin.DalamudInterface?.LocalUiBuilder.HasMainUi ?? false;
+
+ ///
+ public bool HasConfigUi => plugin.DalamudInterface?.LocalUiBuilder.HasMainUi ?? false;
+
+ ///
+ public void OpenMainUi()
+ {
+ if (plugin.DalamudInterface?.LocalUiBuilder.HasMainUi == true)
+ plugin.DalamudInterface.LocalUiBuilder.OpenMain();
+ else
+ throw new InvalidOperationException("Plugin does not have a main UI.");
+ }
+
+ ///
+ public void OpenConfigUi()
+ {
+ if (plugin.DalamudInterface?.LocalUiBuilder.HasConfigUi == true)
+ plugin.DalamudInterface.LocalUiBuilder.OpenConfig();
+ else
+ throw new InvalidOperationException("Plugin does not have a config UI.");
+ }
+}