# AGENTS.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

MindWork AI Studio is a cross-platform desktop application for interacting with Large Language Models (LLMs). The app uses a hybrid architecture combining a Rust Tauri runtime (for the native desktop shell) with a .NET Blazor Server web application (for the UI and business logic).

**Key Architecture Points:**
- **Runtime:** Rust-based Tauri v2 application providing the native window, system integration, and IPC layer
- **App:** .NET 9 Blazor Server application providing the UI and core functionality
- **Communication:** The Rust runtime and .NET app communicate via HTTPS with TLS certificates generated at startup
- **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

### Prerequisites
- .NET 9 SDK
- Rust toolchain (stable)
- Tauri v2 CLI
- Tauri prerequisites (platform-specific dependencies)
- **Note:** Development on Linux is discouraged due to complex Tauri dependencies that vary by distribution

### Build
```bash
cd app/Build
dotnet run build
```
This builds the .NET app as a Tauri "sidecar" binary, which is required even for development.

### Running builds from an agent
Agents must not start builds through their own shell: agent shells run sandboxed, and `.NET` builds
hit a known sandbox issue there, typically surfacing as `CSSM_ModuleLoad()` or other sandbox-related
failures (for reference: https://github.com/openai/codex/issues/4915). This applies to `dotnet run build`,
`dotnet build`, `cargo build`, and similar commands.

Instead, use the JetBrains IDE MCP servers. They execute in the IDE process, which runs outside the
agent sandbox:

- `rider` for the .NET solution at `app/MindWork AI Studio.sln`
- `rustrover` for the Rust runtime at `runtime/`

Pass the `rootFolder` parameter on every call, e.g. the absolute path of the `app` directory for Rider
and of `runtime` for RustRover. It avoids ambiguous calls when several IDE windows are open.

**Compile check of the .NET code:** start `mcp__rider__build_solution_start`, then poll
`mcp__rider__build_solution_state` until its state is `Completed` and read `buildIsSuccess` plus the
collected problems. `mcp__rider__get_project_problems` reports the current Problems View without
triggering a new build.

**Build script commands** such as the canonical build or the I18N collection run through the IDE
terminal, because they are more than a solution build:

```
mcp__rider__execute_terminal_command  command: "cd app/Build && dotnet run build"
mcp__rider__execute_terminal_command  command: "cd app/Build && dotnet run collect-i18n"
```

**Rust builds** work the same way through the matching `rustrover` tools.

Notes:
- The IDE may ask the user to confirm a terminal command. Wait for the result instead of retrying the
  command in the agent shell.
- When the IDE is not running or its MCP server is unavailable, fall back to asking the user to run
  `cd app/Build && dotnet run build` locally, and wait for their feedback before diagnosing issues or
  making follow-up changes.
- Treat the build output, error messages, or success confirmation as the source of truth for further
  troubleshooting, no matter whether it came from the MCP server or from the user.

### Running Tests
Currently, no automated test suite exists in the repository.

## Architecture Details

### Rust Runtime (`runtime/`)
**Entry point:** `runtime/src/main.rs`

Key modules:
- `app_window.rs` - Tauri window management, updater integration
- `dotnet.rs` - Launches and manages the .NET sidecar process
- `runtime_api.rs` - Axum-based HTTPS API for .NET ↔ Rust communication
- `certificate.rs` - Generates self-signed TLS certificates for secure IPC
- `secret.rs` - Secure secret storage using OS keyring (Keychain/Credential Manager)
- `clipboard.rs` - Cross-platform clipboard operations
- `file_data.rs` - File processing for RAG (extracts text from PDF, DOCX, XLSX, PPTX, etc.)
- `encryption.rs` - AES-256-CBC encryption for sensitive data
- `pandoc.rs` - Integration with Pandoc for document conversion
- `log.rs` - Logging infrastructure using `flexi_logger`

### .NET App (`app/MindWork AI Studio/`)
**Entry point:** `app/MindWork AI Studio/Program.cs`

Key structure:
- **Program.cs** - Bootstraps Blazor Server, configures Kestrel, initializes encryption and Rust service
- **Provider/** - LLM provider implementations (OpenAI, Anthropic, Google, Mistral, etc.)
  - `BaseProvider.cs` - Abstract base for all providers with streaming support
  - `IProvider.cs` - Provider interface defining capabilities and streaming methods
- **Chat/** - Chat functionality and message handling
- **Assistants/** - Pre-configured assistants (translation, summarization, coding, etc.)
  - `AssistantBase.razor` - Base component for all assistants
- **Agents/** - contains all agents, e.g., for data source selection, context validation, etc.
  - `AgentDataSourceSelection.cs` - Selects appropriate data sources for queries
  - `AgentRetrievalContextValidation.cs` - Validates retrieved context relevance
- **Tools/PluginSystem/** - Lua-based plugin system
- **Tools/Services/** - Core background services (settings, message bus, data sources, updates)
- **Tools/Rust/** - .NET wrapper for Rust API calls
- **Settings/** - Application settings and data models
- **Components/** - Reusable Blazor components
- **Pages/** - Top-level page components

### IPC Communication Flow
1. Rust runtime starts and generates TLS certificate
2. Rust starts internal HTTPS API on random port
3. Rust launches .NET sidecar, passing: API port, certificate fingerprint, API token, secret key
4. .NET reads environment variables and establishes secure HTTPS connection to Rust
5. .NET requests an app port from Rust, starts Blazor Server on that port
6. Rust opens Tauri webview pointing to localhost:app_port
7. Bi-directional communication: .NET ↔ Rust via HTTPS API

### Configuration and Metadata
- `metadata.txt` - Build metadata (version, build time, component versions) read by both Rust and .NET
- `startup.env` - Development environment variables (generated by build script)
- `.NET project` reads metadata.txt at build time and injects as assembly attributes

## Plugin System

**Location:** `app/MindWork AI Studio/Plugins/`

Plugins are written in Lua and provide:
- **Language plugins** - I18N translations (e.g., German language pack)
- **Configuration plugins** - Enterprise IT configurations for centrally managed providers, settings
- **Future:** Assistant plugins for custom assistants

**Example configuration plugin:** `app/MindWork AI Studio/Plugins/configuration/plugin.lua`

Plugins can configure:
- Self-hosted LLM providers
- Update behavior
- Preview features visibility
- Preselected profiles
- Chat templates
- etc.

Configuration plugins provide three kinds of values:
- **Managed settings:** simple values such as booleans, numbers, strings, enums, lists, or sets handled through `ManagedConfiguration`. These values may be locked or used as organization defaults. Which configuration plugin owns a locked setting is persisted in `Data.ManagedLockedConfigurations`, and organization defaults are tracked in `Data.ManagedEditableDefaults`. Both are cleaned up generically by `ManagedConfiguration.CleanupLeftOverManagedConfigurations(...)` when the owning plugin is gone. The value a setting had before a configuration plugin took it over is kept in `Data.ManagedUserValueSnapshots` and restored by that same clean-up, so removing a plugin hands the user's own value back instead of the app default.
- **Managed configuration objects:** complex Lua tables that are persisted into `SettingsManager.ConfigurationData`, implement `IConfigurationObject`, and are cleaned up through `PluginConfigurationObject.CleanLeftOverConfigurationObjects(...)`. Examples include providers, profiles, chat templates, data sources, and document analysis policies.
- **Live plugin content:** complex Lua tables that implement `ILivePluginContent` and are read live from running plugins instead of being persisted to `ConfigurationData`. Examples include `MANDATORY_INFOS` and `INTRODUCTIONS`. If live plugin content creates persistent side data, add a dedicated cleanup path for that side data, like mandatory-info acceptances.

When adding configuration plugin capabilities:
- For managed settings, update the corresponding data class in `app/MindWork AI Studio/Settings/DataModel/` to call `ManagedConfiguration.Register(...)` and process the setting in `PluginConfiguration.TryProcessConfiguration`. Cleaning up the setting when its configuration plugin was removed needs no extra step: `ManagedConfiguration.CleanupLeftOverManagedConfigurations(...)` iterates all registered settings. Do not add per-setting cleanup calls to `PluginFactory.Loading.LoadAll`.
- For managed configuration objects, update `PluginConfigurationObject.cs` and `PluginConfigurationObjectType.cs`, persist them in the appropriate `ConfigurationData` collection, and add cleanup via `PluginConfigurationObject.CleanLeftOverConfigurationObjects(...)`.
- For live plugin content, add a data type implementing `ILivePluginContent`, parse it in `PluginConfiguration`, expose it through `PluginFactory`, and add any required cleanup only for persistent side data.
- Always document the new capability in `app/MindWork AI Studio/Plugins/configuration/plugin.lua`.

## RAG (Retrieval-Augmented Generation)

RAG integration is currently in development (preview feature). Architecture:
- **External Retrieval Interface (ERI)** - Contract for integrating external data sources
- **Data Sources** - Local files and external data via ERI servers
- **Agents** - AI agents select data sources and validate retrieval quality
- **Embedding providers** - Support for various embedding models
- **Vector database** - Planned integration with Qdrant for vector storage
- **File processing** - Extracts text from PDF, DOCX, XLSX via Rust runtime

## Enterprise IT Support

AI Studio supports centralized configuration for enterprise environments:
- **Registry (Windows)** or **environment variables** (all platforms) specify configuration server URL and ID
- Configuration downloaded as ZIP containing Lua plugin
- Checks for updates every ~16 minutes via ETag
- Allows IT departments to pre-configure providers, settings, and chat templates

**Documentation:** `documentation/Enterprise IT.md`

## Provider Confidence System

Multi-level confidence scheme allows users to control which providers see which data:
- Confidence levels: e.g. `NONE`, `LOW`, `MEDIUM`, `HIGH`, and some more granular levels
- Each assistant/feature can require a minimum confidence level
- Users assign confidence levels to providers based on trust

**Implementation:** `app/MindWork AI Studio/Provider/Confidence.cs`

## Dependencies and Frameworks

**Rust:**
- Tauri 2 - Desktop application framework
- Axum - HTTPS API server
- tokio - Async runtime
- keyring - OS keyring integration
- pdfium-render - PDF text extraction
- calamine - Excel file parsing

**.NET:**
- Blazor Server - UI framework
- MudBlazor - Component library
- LuaCSharp - Lua scripting engine
- HtmlAgilityPack - HTML parsing
- ReverseMarkdown - HTML to Markdown conversion

## Security

- **Encryption:** AES-256-CBC with PBKDF2 key derivation for sensitive data
- **IPC:** TLS-secured communication with random ports and API tokens
- **Secrets:** OS keyring for persistent secret storage (API keys, etc.)
- **Sandboxing:** Tauri provides OS-level sandboxing

## Release Process

1. Create changelog file: `app/MindWork AI Studio/wwwroot/changelog/vX.Y.Z.md`
2. Commit changelog
3. Run from `app/Build`: `dotnet run release --action <build|month|year>`
4. Create PR with version bump and changes
5. After PR merge, maintainer creates git tag: `vX.Y.Z`
6. GitHub Actions builds release binaries for all platforms
7. Binaries uploaded to GitHub Releases

## Important Development Notes

- **File changes require Write/Edit tools** - Never use bash commands like `cat <<EOF` or `echo >`
- **End of file formatting** - Do not append an extra empty line at the end of files.
- **No automated formatting for Rust or .NET files** - Never run automated formatters on Rust files (`.rs`) or .NET files (`.cs`, `.razor`, `.csproj`, etc.). Only make the minimal manual formatting changes required for the specific edit.
- **I18N resources are generated** - Do not manually edit `app/MindWork AI Studio/Assistants/I18N/allTexts.lua`, `app/MindWork AI Studio/Plugins/languages/en-us-97dfb1ba-50c4-4440-8dfa-6575daf543c8/plugin.lua`, or `app/MindWork AI Studio/Plugins/languages/de-de-43065dbc-78d0-45b7-92be-f14c2926e2dc/plugin.lua`. These files are updated automatically by the I18N process.
- **Spaces in paths** - Always quote paths with spaces in bash commands
- **Agent-run builds** - Never start `.NET` or Rust builds in the agent's own shell; it is sandboxed. Use the `rider` and `rustrover` MCP servers instead, which build in the IDE outside that sandbox. See "Running builds from an agent" above.
- **Debug environment** - Reads `startup.env` file with IPC credentials
- **Production environment** - Runtime launches .NET sidecar with environment variables
- **MudBlazor** - Component library requires DI setup in Program.cs
- **Encryption** - Initialized before Rust service is marked ready
- **Message Bus** - Singleton event bus for cross-component communication inside the .NET app
- **Naming conventions** - Constants, enum members, and `static readonly` fields use `UPPER_SNAKE_CASE` such as `MY_CONSTANT`.
- **Compatibility shims** - Temporary fallback or read-repair code must be documented in `documentation/compatibility-shims/` with an introduced date, remove-after date, code references, and removal checklist. Add a short code comment near the shim that references the document and remove-after date. Check this folder before adding similar fallback logic, and do not extend expired shims without explicit maintainer direction. Do not use this process for permanent settings schema migrations; those belong in `app/MindWork AI Studio/Settings/SettingsMigrations.cs`.
- **Empty lines** - Avoid adding extra empty lines at the end of files.

## Changelogs
Changelogs are located in `app/MindWork AI Studio/wwwroot/changelog/` with filenames `vX.Y.Z.md`. These changelogs are meant to be for normal end-users
and should be written in a non-technical way, focusing on user-facing changes and improvements. Additionally, changes made regarding the plugin system
should be included in the changelog, especially if they affect how users can configure the app or if they introduce new capabilities for plugins. Plugin
developers should also be informed about these changes, as they might need to update their plugins accordingly. When adding entries to the changelog,
please ensure they are clear and concise, avoiding technical jargon where possible. Each entry starts with a dash and a space (`- `) and one of the
following words:

- Added
- Released
- Improved
- Changed
- Fixed
- Updated
- Removed
- Downgraded
- Upgraded

The entire changelog is sorted by these categories in the order shown above. The language used for the changelog is US English.