diff --git a/CLAUDE.md b/CLAUDE.md
index 14aba589..689378d2 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -13,7 +13,7 @@ MindWork AI Studio is a cross-platform desktop application for interacting with
- **Providers:** Multi-provider architecture supporting OpenAI, Anthropic, Google, Mistral, Perplexity, self-hosted models, and others
- **Plugin System:** Lua-based plugin system for language packs, configuration, and future assistant plugins
-## Building and Running
+## Building
### Prerequisites
- .NET 9 SDK
@@ -22,39 +22,16 @@ MindWork AI Studio is a cross-platform desktop application for interacting with
- Tauri prerequisites (platform-specific dependencies)
- **Note:** Development on Linux is discouraged due to complex Tauri dependencies that vary by distribution
-### One-Time Setup
+### Build
```bash
cd app/Build
dotnet run build
```
This builds the .NET app as a Tauri "sidecar" binary, which is required even for development.
-### Development Workflow
-Run these commands in separate terminals:
-
-**Terminal 1 - Start Rust runtime:**
-```bash
-cd runtime
-cargo tauri dev --no-watch
-```
-
-**Terminal 2 - Start .NET app:**
-```bash
-cd "app/MindWork AI Studio"
-dotnet run
-```
-
-The app will start in the Tauri window. Hot reload is supported for .NET code changes.
-
-### Building for Production
-```bash
-cd app/Build
-dotnet run build
-```
-Creates a release build for the current platform and architecture. Output is in `runtime/target/release/`.
### Running Tests
-Currently no automated test suite exists in the repository.
+Currently, no automated test suite exists in the repository.
## Architecture Details
@@ -125,6 +102,14 @@ Plugins can configure:
- Preview features visibility
- Preselected profiles
- Chat templates
+- etc.
+
+When adding configuration options, update:
+- `app/MindWork AI Studio/Tools/PluginSystem/PluginConfiguration.cs`: In method `TryProcessConfiguration` register new options.
+- `app/MindWork AI Studio/Tools/PluginSystem/PluginFactory.Loading.cs`: In method `LoadAll` check for leftover configuration.
+- The corresponding data class in `app/MindWork AI Studio/Settings/DataModel/` to call `ManagedConfiguration.Register(...)`, when adding config options (in contrast to complex config. objects)
+- `app/MindWork AI Studio/Tools/PluginSystem/PluginConfigurationObject.cs` for parsing logic of complex configuration objects.
+- `app/MindWork AI Studio/Plugins/configuration/plugin.lua` to document the new configuration option.
## RAG (Retrieval-Augmented Generation)
diff --git a/app/MindWork AI Studio/Components/AssistantBlock.razor b/app/MindWork AI Studio/Components/AssistantBlock.razor
index 754a9e24..372fae7e 100644
--- a/app/MindWork AI Studio/Components/AssistantBlock.razor
+++ b/app/MindWork AI Studio/Components/AssistantBlock.razor
@@ -1,30 +1,33 @@
@inherits MSGComponentBase
@typeparam TSettings
-
-
-
-
-
-
- @this.Name
+@if (this.IsVisible)
+{
+
+
+
+
+
+
+ @this.Name
+
+
+
+
+
+
+
+ @this.Description
-
-
-
-
-
- @this.Description
-
-
-
-
-
-
- @this.ButtonText
-
-
-
-
-
\ No newline at end of file
+
+
+
+
+ @this.ButtonText
+
+
+
+
+
+}
\ No newline at end of file
diff --git a/app/MindWork AI Studio/Components/AssistantBlock.razor.cs b/app/MindWork AI Studio/Components/AssistantBlock.razor.cs
index ef0e7a4d..69dfe49b 100644
--- a/app/MindWork AI Studio/Components/AssistantBlock.razor.cs
+++ b/app/MindWork AI Studio/Components/AssistantBlock.razor.cs
@@ -1,3 +1,5 @@
+using AIStudio.Settings.DataModel;
+
using Microsoft.AspNetCore.Components;
using DialogOptions = AIStudio.Dialogs.DialogOptions;
@@ -8,32 +10,38 @@ public partial class AssistantBlock : MSGComponentBase where TSetting
{
[Parameter]
public string Name { get; set; } = string.Empty;
-
+
[Parameter]
public string Description { get; set; } = string.Empty;
-
+
[Parameter]
public string Icon { get; set; } = Icons.Material.Filled.DisabledByDefault;
-
+
[Parameter]
public string ButtonText { get; set; } = "Start";
-
+
[Parameter]
public string Link { get; set; } = string.Empty;
-
+
+ [Parameter]
+ public Tools.Components Component { get; set; } = Tools.Components.NONE;
+
+ [Parameter]
+ public PreviewFeatures RequiredPreviewFeature { get; set; } = PreviewFeatures.NONE;
+
[Inject]
private MudTheme ColorTheme { get; init; } = null!;
-
+
[Inject]
private IDialogService DialogService { get; init; } = null!;
private async Task OpenSettingsDialog()
{
var dialogParameters = new DialogParameters();
-
+
await this.DialogService.ShowAsync(T("Open Settings"), dialogParameters, DialogOptions.FULLSCREEN);
}
-
+
private string BorderColor => this.SettingsManager.IsDarkMode switch
{
true => this.ColorTheme.GetCurrentPalette(this.SettingsManager).GrayLight,
@@ -41,4 +49,6 @@ public partial class AssistantBlock : MSGComponentBase where TSetting
};
private string BlockStyle => $"border-width: 2px; border-color: {this.BorderColor}; border-radius: 12px; border-style: solid; max-width: 20em;";
+
+ private bool IsVisible => this.SettingsManager.IsAssistantVisible(this.Component, assistantName: this.Name, requiredPreviewFeature: this.RequiredPreviewFeature);
}
\ No newline at end of file
diff --git a/app/MindWork AI Studio/Pages/Assistants.razor b/app/MindWork AI Studio/Pages/Assistants.razor
index 1cd72a5f..250aa06c 100644
--- a/app/MindWork AI Studio/Pages/Assistants.razor
+++ b/app/MindWork AI Studio/Pages/Assistants.razor
@@ -9,60 +9,88 @@
-
-
- @T("General")
-
-
-
-
-
-
-
-
-
- @T("Business")
-
-
-
-
- @if (PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025.IsEnabled(this.SettingsManager))
- {
-
- }
-
-
-
-
-
-
-
+ @if (this.SettingsManager.IsAnyCategoryAssistantVisible("General",
+ (Components.TEXT_SUMMARIZER_ASSISTANT, PreviewFeatures.NONE),
+ (Components.TRANSLATION_ASSISTANT, PreviewFeatures.NONE),
+ (Components.GRAMMAR_SPELLING_ASSISTANT, PreviewFeatures.NONE),
+ (Components.REWRITE_ASSISTANT, PreviewFeatures.NONE),
+ (Components.SYNONYMS_ASSISTANT, PreviewFeatures.NONE)
+ ))
+ {
+
+ @T("General")
+
+
+
+
+
+
+
+
+ }
-
- @T("Learning")
-
-
-
-
-
-
- @T("Software Engineering")
-
-
-
- @if (PreviewFeatures.PRE_RAG_2024.IsEnabled(this.SettingsManager))
- {
-
- }
-
-
-
- @T("AI Studio Development")
-
-
-
-
+ @if (this.SettingsManager.IsAnyCategoryAssistantVisible("Business",
+ (Components.EMAIL_ASSISTANT, PreviewFeatures.NONE),
+ (Components.DOCUMENT_ANALYSIS_ASSISTANT, PreviewFeatures.PRE_DOCUMENT_ANALYSIS_2025),
+ (Components.MY_TASKS_ASSISTANT, PreviewFeatures.NONE),
+ (Components.AGENDA_ASSISTANT, PreviewFeatures.NONE),
+ (Components.JOB_POSTING_ASSISTANT, PreviewFeatures.NONE),
+ (Components.LEGAL_CHECK_ASSISTANT, PreviewFeatures.NONE),
+ (Components.ICON_FINDER_ASSISTANT, PreviewFeatures.NONE)
+ ))
+ {
+
+ @T("Business")
+
+
+
+
+
+
+
+
+
+
+ }
+
+ @if (this.SettingsManager.IsAnyCategoryAssistantVisible("Learning",
+ (Components.BIAS_DAY_ASSISTANT, PreviewFeatures.NONE)
+ ))
+ {
+
+ @T("Learning")
+
+
+
+
+ }
+
+ @if (this.SettingsManager.IsAnyCategoryAssistantVisible("Software Engineering",
+ (Components.CODING_ASSISTANT, PreviewFeatures.NONE),
+ (Components.ERI_ASSISTANT, PreviewFeatures.PRE_RAG_2024)
+ ))
+ {
+
+ @T("Software Engineering")
+
+
+
+
+
+ }
+
+ @if (this.SettingsManager.IsAnyCategoryAssistantVisible("AI Studio Development",
+ (Components.I18N_ASSISTANT, PreviewFeatures.NONE)
+ ))
+ {
+
+ @T("AI Studio Development")
+
+
+
+
+ }
-
\ No newline at end of file
+
diff --git a/app/MindWork AI Studio/Plugins/configuration/plugin.lua b/app/MindWork AI Studio/Plugins/configuration/plugin.lua
index 8cd62555..9708c666 100644
--- a/app/MindWork AI Studio/Plugins/configuration/plugin.lua
+++ b/app/MindWork AI Studio/Plugins/configuration/plugin.lua
@@ -143,6 +143,16 @@ CONFIG["SETTINGS"] = {}
-- Please note: using an empty string ("") will lock the selection and disable dictation/transcription.
-- CONFIG["SETTINGS"]["DataApp.UseTranscriptionProvider"] = "00000000-0000-0000-0000-000000000000"
+-- Configure which assistants should be hidden from the UI.
+-- Allowed values are:
+-- GRAMMAR_SPELLING_ASSISTANT, ICON_FINDER_ASSISTANT, REWRITE_ASSISTANT,
+-- TRANSLATION_ASSISTANT, AGENDA_ASSISTANT, CODING_ASSISTANT,
+-- TEXT_SUMMARIZER_ASSISTANT, EMAIL_ASSISTANT, LEGAL_CHECK_ASSISTANT,
+-- SYNONYMS_ASSISTANT, MY_TASKS_ASSISTANT, JOB_POSTING_ASSISTANT,
+-- BIAS_DAY_ASSISTANT, ERI_ASSISTANT, DOCUMENT_ANALYSIS_ASSISTANT,
+-- I18N_ASSISTANT
+-- CONFIG["SETTINGS"]["DataApp.HiddenAssistants"] = { "ERI_ASSISTANT", "I18N_ASSISTANT" }
+
-- Example chat templates for this configuration:
CONFIG["CHAT_TEMPLATES"] = {}
diff --git a/app/MindWork AI Studio/Settings/ConfigurableAssistant.cs b/app/MindWork AI Studio/Settings/ConfigurableAssistant.cs
new file mode 100644
index 00000000..f1076d9e
--- /dev/null
+++ b/app/MindWork AI Studio/Settings/ConfigurableAssistant.cs
@@ -0,0 +1,30 @@
+namespace AIStudio.Settings;
+
+///
+/// Enum representing assistants that can be hidden via configuration plugin.
+///
+public enum ConfigurableAssistant
+{
+ NONE = 0,
+ UNKNOWN = 1,
+
+ GRAMMAR_SPELLING_ASSISTANT,
+ ICON_FINDER_ASSISTANT,
+ REWRITE_ASSISTANT,
+ TRANSLATION_ASSISTANT,
+ AGENDA_ASSISTANT,
+ CODING_ASSISTANT,
+ TEXT_SUMMARIZER_ASSISTANT,
+ EMAIL_ASSISTANT,
+ LEGAL_CHECK_ASSISTANT,
+ SYNONYMS_ASSISTANT,
+ MY_TASKS_ASSISTANT,
+ JOB_POSTING_ASSISTANT,
+ BIAS_DAY_ASSISTANT,
+ ERI_ASSISTANT,
+ DOCUMENT_ANALYSIS_ASSISTANT,
+
+ // ReSharper disable InconsistentNaming
+ I18N_ASSISTANT,
+ // ReSharper restore InconsistentNaming
+}
diff --git a/app/MindWork AI Studio/Settings/DataModel/DataApp.cs b/app/MindWork AI Studio/Settings/DataModel/DataApp.cs
index 720d3b5a..d2ac4bb7 100644
--- a/app/MindWork AI Studio/Settings/DataModel/DataApp.cs
+++ b/app/MindWork AI Studio/Settings/DataModel/DataApp.cs
@@ -86,4 +86,9 @@ public sealed class DataApp(Expression>? configSelection = n
/// Should the user be allowed to add providers?
///
public bool AllowUserToAddProvider { get; set; } = ManagedConfiguration.Register(configSelection, n => n.AllowUserToAddProvider, true);
+
+ ///
+ /// List of assistants that should be hidden from the UI.
+ ///
+ public HashSet HiddenAssistants { get; set; } = ManagedConfiguration.Register(configSelection, n => n.HiddenAssistants, []);
}
\ No newline at end of file
diff --git a/app/MindWork AI Studio/Settings/DataModel/PreviewFeatures.cs b/app/MindWork AI Studio/Settings/DataModel/PreviewFeatures.cs
index d74898dd..e58ecdca 100644
--- a/app/MindWork AI Studio/Settings/DataModel/PreviewFeatures.cs
+++ b/app/MindWork AI Studio/Settings/DataModel/PreviewFeatures.cs
@@ -2,6 +2,8 @@ namespace AIStudio.Settings.DataModel;
public enum PreviewFeatures
{
+ NONE = 0,
+
//
// Important: Never delete any enum value from this list.
// We must be able to deserialize old settings files that may contain these values.
diff --git a/app/MindWork AI Studio/Tools/AssistantVisibilityExtensions.cs b/app/MindWork AI Studio/Tools/AssistantVisibilityExtensions.cs
new file mode 100644
index 00000000..cb4e7fdc
--- /dev/null
+++ b/app/MindWork AI Studio/Tools/AssistantVisibilityExtensions.cs
@@ -0,0 +1,100 @@
+using AIStudio.Settings;
+using AIStudio.Settings.DataModel;
+
+namespace AIStudio.Tools;
+
+///
+/// Extension methods for checking assistant visibility based on configuration and preview features.
+///
+public static class AssistantVisibilityExtensions
+{
+ private static readonly ILogger LOGGER = Program.LOGGER_FACTORY.CreateLogger(nameof(AssistantVisibilityExtensions));
+
+ ///
+ /// Checks if an assistant should be visible based on configuration and optional preview feature requirements.
+ ///
+ /// The settings manager to check configuration against.
+ /// Whether to log visibility decisions.
+ /// The name of the assistant to check (for logging purposes).
+ /// The assistant component to check.
+ /// Optional preview feature that must be enabled for the assistant to be visible.
+ /// True if the assistant should be visible, false otherwise.
+ public static bool IsAssistantVisible(this SettingsManager settingsManager, Components component, bool withLogging = true, string assistantName = "", PreviewFeatures requiredPreviewFeature = PreviewFeatures.NONE)
+ {
+ withLogging = withLogging && !string.IsNullOrWhiteSpace(assistantName);
+
+ // Check if a preview feature is required and enabled:
+ if (requiredPreviewFeature != PreviewFeatures.NONE && !requiredPreviewFeature.IsEnabled(settingsManager))
+ {
+ if(withLogging)
+ LOGGER.LogInformation("Assistant '{AssistantName}' is not visible because the required preview feature '{PreviewFeature}' is not enabled.", assistantName, requiredPreviewFeature);
+
+ return false;
+ }
+
+ // If no component is specified, it's always visible:
+ if (component is Components.NONE)
+ {
+ if(withLogging)
+ LOGGER.LogWarning("Assistant '{AssistantName}' is visible because no component is specified.", assistantName);
+
+ return true;
+ }
+
+ // Map Components enum to ConfigurableAssistant enum:
+ var configurableAssistant = component switch
+ {
+ Components.GRAMMAR_SPELLING_ASSISTANT => ConfigurableAssistant.GRAMMAR_SPELLING_ASSISTANT,
+ Components.ICON_FINDER_ASSISTANT => ConfigurableAssistant.ICON_FINDER_ASSISTANT,
+ Components.REWRITE_ASSISTANT => ConfigurableAssistant.REWRITE_ASSISTANT,
+ Components.TRANSLATION_ASSISTANT => ConfigurableAssistant.TRANSLATION_ASSISTANT,
+ Components.AGENDA_ASSISTANT => ConfigurableAssistant.AGENDA_ASSISTANT,
+ Components.CODING_ASSISTANT => ConfigurableAssistant.CODING_ASSISTANT,
+ Components.TEXT_SUMMARIZER_ASSISTANT => ConfigurableAssistant.TEXT_SUMMARIZER_ASSISTANT,
+ Components.EMAIL_ASSISTANT => ConfigurableAssistant.EMAIL_ASSISTANT,
+ Components.LEGAL_CHECK_ASSISTANT => ConfigurableAssistant.LEGAL_CHECK_ASSISTANT,
+ Components.SYNONYMS_ASSISTANT => ConfigurableAssistant.SYNONYMS_ASSISTANT,
+ Components.MY_TASKS_ASSISTANT => ConfigurableAssistant.MY_TASKS_ASSISTANT,
+ Components.JOB_POSTING_ASSISTANT => ConfigurableAssistant.JOB_POSTING_ASSISTANT,
+ Components.BIAS_DAY_ASSISTANT => ConfigurableAssistant.BIAS_DAY_ASSISTANT,
+ Components.ERI_ASSISTANT => ConfigurableAssistant.ERI_ASSISTANT,
+ Components.DOCUMENT_ANALYSIS_ASSISTANT => ConfigurableAssistant.DOCUMENT_ANALYSIS_ASSISTANT,
+ Components.I18N_ASSISTANT => ConfigurableAssistant.I18N_ASSISTANT,
+
+ _ => ConfigurableAssistant.UNKNOWN,
+ };
+
+ // If the component doesn't map to a configurable assistant, it's always visible:
+ if (configurableAssistant is ConfigurableAssistant.UNKNOWN)
+ {
+ if(withLogging)
+ LOGGER.LogWarning("Assistant '{AssistantName}' is visible because its component '{Component}' does not map to a configurable assistant.", assistantName, component);
+
+ return true;
+ }
+
+ // Check if the assistant is hidden by any configuration plugin:
+ var isHidden = settingsManager.ConfigurationData.App.HiddenAssistants.Contains(configurableAssistant);
+ if (isHidden && withLogging)
+ LOGGER.LogInformation("Assistant '{AssistantName}' is hidden based on the configuration.", assistantName);
+
+ return !isHidden;
+ }
+
+ ///
+ /// Checks if any assistant in a category should be visible.
+ ///
+ /// The settings manager to check configuration against.
+ /// The name of the assistant category (for logging purposes).
+ /// The assistants in the category with their optional preview feature requirements.
+ /// True if at least one assistant in the category should be visible, false otherwise.
+ public static bool IsAnyCategoryAssistantVisible(this SettingsManager settingsManager, string categoryName, params (Components Component, PreviewFeatures RequiredPreviewFeature)[] assistants)
+ {
+ foreach (var (component, requiredPreviewFeature) in assistants)
+ if (settingsManager.IsAssistantVisible(component, withLogging: false, requiredPreviewFeature: requiredPreviewFeature))
+ return true;
+
+ LOGGER.LogInformation("No assistants in category '{CategoryName}' are visible.", categoryName);
+ return false;
+ }
+}
diff --git a/app/MindWork AI Studio/Tools/PluginSystem/PluginConfiguration.cs b/app/MindWork AI Studio/Tools/PluginSystem/PluginConfiguration.cs
index 76148218..814aa971 100644
--- a/app/MindWork AI Studio/Tools/PluginSystem/PluginConfiguration.cs
+++ b/app/MindWork AI Studio/Tools/PluginSystem/PluginConfiguration.cs
@@ -67,6 +67,9 @@ public sealed class PluginConfiguration(bool isInternal, LuaState state, PluginT
// Config: enabled preview features
ManagedConfiguration.TryProcessConfiguration(x => x.App, x => x.EnabledPreviewFeatures, this.Id, settingsTable, dryRun);
+ // Config: hide some assistants?
+ ManagedConfiguration.TryProcessConfiguration(x => x.App, x => x.HiddenAssistants, this.Id, settingsTable, dryRun);
+
// Handle configured LLM providers:
PluginConfigurationObject.TryParse(PluginConfigurationObjectType.LLM_PROVIDER, x => x.Providers, x => x.NextProviderNum, mainTable, this.Id, ref this.configObjects, dryRun);
diff --git a/app/MindWork AI Studio/Tools/PluginSystem/PluginFactory.Loading.cs b/app/MindWork AI Studio/Tools/PluginSystem/PluginFactory.Loading.cs
index 2efbde97..63eb3df5 100644
--- a/app/MindWork AI Studio/Tools/PluginSystem/PluginFactory.Loading.cs
+++ b/app/MindWork AI Studio/Tools/PluginSystem/PluginFactory.Loading.cs
@@ -177,6 +177,10 @@ public static partial class PluginFactory
if(ManagedConfiguration.IsConfigurationLeftOver(x => x.App, x => x.UseTranscriptionProvider, AVAILABLE_PLUGINS))
wasConfigurationChanged = true;
+ // Check for hidden assistants:
+ if(ManagedConfiguration.IsConfigurationLeftOver(x => x.App, x => x.HiddenAssistants, AVAILABLE_PLUGINS))
+ wasConfigurationChanged = true;
+
if (wasConfigurationChanged)
{
await SETTINGS_MANAGER.StoreSettings();
diff --git a/app/MindWork AI Studio/wwwroot/changelog/v26.1.2.md b/app/MindWork AI Studio/wwwroot/changelog/v26.1.2.md
index 4e5fd360..b05871b0 100644
--- a/app/MindWork AI Studio/wwwroot/changelog/v26.1.2.md
+++ b/app/MindWork AI Studio/wwwroot/changelog/v26.1.2.md
@@ -1 +1,2 @@
# v26.1.2, build 232 (2026-01-xx xx:xx UTC)
+- Added the option to hide specific assistants by configuration plugins. This is useful for enterprise environments in organizations.
\ No newline at end of file