Fixed an issue where AI Studio could be started multiple times (#803)
Some checks are pending
Build and Release / Read metadata (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-apple-darwin, osx-arm64, macos-latest, aarch64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-pc-windows-msvc.exe, win-arm64, windows-latest, aarch64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-aarch64-unknown-linux-gnu, linux-arm64, ubuntu-22.04-arm, aarch64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-apple-darwin, osx-x64, macos-latest, x86_64-apple-darwin, dmg,app,updater, dmg) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-pc-windows-msvc.exe, win-x64, windows-latest, x86_64-pc-windows-msvc, nsis,updater, nsis) (push) Blocked by required conditions
Build and Release / Build app (${{ matrix.dotnet_runtime }}) (-x86_64-unknown-linux-gnu, linux-x64, ubuntu-22.04, x86_64-unknown-linux-gnu, appimage,updater, appimage) (push) Blocked by required conditions
Build and Release / Prepare & create release (push) Blocked by required conditions
Build and Release / Determine run mode (push) Waiting to run
Build and Release / Publish release (push) Blocked by required conditions

This commit is contained in:
Thorsten Sommer 2026-06-10 21:31:02 +02:00 committed by GitHub
parent c07a5227dc
commit f017b87abd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 50 additions and 12 deletions

View File

@ -7,7 +7,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
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). 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:** **Key Architecture Points:**
- **Runtime:** Rust-based Tauri v1.8 application providing the native window, system integration, and IPC layer - **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 - **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 - **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 - **Providers:** Multi-provider architecture supporting OpenAI, Anthropic, Google, Mistral, Perplexity, self-hosted models, and others
@ -18,7 +18,7 @@ MindWork AI Studio is a cross-platform desktop application for interacting with
### Prerequisites ### Prerequisites
- .NET 9 SDK - .NET 9 SDK
- Rust toolchain (stable) - Rust toolchain (stable)
- Tauri v1.6.2 CLI: `cargo install --version 1.6.2 tauri-cli` - Tauri v2 CLI
- Tauri prerequisites (platform-specific dependencies) - Tauri prerequisites (platform-specific dependencies)
- **Note:** Development on Linux is discouraged due to complex Tauri dependencies that vary by distribution - **Note:** Development on Linux is discouraged due to complex Tauri dependencies that vary by distribution
@ -151,7 +151,7 @@ Multi-level confidence scheme allows users to control which providers see which
## Dependencies and Frameworks ## Dependencies and Frameworks
**Rust:** **Rust:**
- Tauri 1.8 - Desktop application framework - Tauri 2 - Desktop application framework
- Axum - HTTPS API server - Axum - HTTPS API server
- tokio - Async runtime - tokio - Async runtime
- keyring - OS keyring integration - keyring - OS keyring integration

View File

@ -14,4 +14,5 @@
- Fixed an issue where renamed chat templates and profiles continued to show their old names in the chat toolbar until the app was restarted. - Fixed an issue where renamed chat templates and profiles continued to show their old names in the chat toolbar until the app was restarted.
- Fixed workspace creation and renaming to prevent new workspaces from using an existing name. - Fixed workspace creation and renaming to prevent new workspaces from using an existing name.
- Fixed an issue on Microsoft Windows where reading attached documents could briefly open a terminal window while processing files. - Fixed an issue on Microsoft Windows where reading attached documents could briefly open a terminal window while processing files.
- Fixed an issue where AI Studio could be started multiple times on Microsoft Windows by launching it from different virtual desktops.
- Upgraded dependencies. - Upgraded dependencies.

34
runtime/Cargo.lock generated
View File

@ -214,7 +214,7 @@ dependencies = [
"objc2-foundation 0.3.2", "objc2-foundation 0.3.2",
"parking_lot", "parking_lot",
"percent-encoding", "percent-encoding",
"windows-sys 0.59.0", "windows-sys 0.60.2",
"x11rb", "x11rb",
] ]
@ -1769,7 +1769,7 @@ dependencies = [
"libc", "libc",
"option-ext", "option-ext",
"redox_users", "redox_users",
"windows-sys 0.59.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -2066,7 +2066,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.59.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -3828,7 +3828,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"windows-targets 0.48.5", "windows-targets 0.52.6",
] ]
[[package]] [[package]]
@ -4041,6 +4041,7 @@ dependencies = [
"tauri-plugin-global-shortcut", "tauri-plugin-global-shortcut",
"tauri-plugin-opener", "tauri-plugin-opener",
"tauri-plugin-shell", "tauri-plugin-shell",
"tauri-plugin-single-instance",
"tauri-plugin-updater", "tauri-plugin-updater",
"tauri-plugin-window-state", "tauri-plugin-window-state",
"tempfile", "tempfile",
@ -4350,7 +4351,7 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8"
dependencies = [ dependencies = [
"proc-macro-crate 1.3.1", "proc-macro-crate 3.5.0",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.117", "syn 2.0.117",
@ -5393,7 +5394,7 @@ dependencies = [
"once_cell", "once_cell",
"socket2", "socket2",
"tracing", "tracing",
"windows-sys 0.59.0", "windows-sys 0.60.2",
] ]
[[package]] [[package]]
@ -5813,7 +5814,7 @@ dependencies = [
"errno", "errno",
"libc", "libc",
"linux-raw-sys 0.12.1", "linux-raw-sys 0.12.1",
"windows-sys 0.59.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -5872,7 +5873,7 @@ dependencies = [
"security-framework", "security-framework",
"security-framework-sys", "security-framework-sys",
"webpki-root-certs", "webpki-root-certs",
"windows-sys 0.59.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]
@ -7005,6 +7006,21 @@ dependencies = [
"tokio", "tokio",
] ]
[[package]]
name = "tauri-plugin-single-instance"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c8f29386f5e9fdc699182388a33ee80a56de436d91b67459e86afef426282af"
dependencies = [
"serde",
"serde_json",
"tauri",
"thiserror 2.0.18",
"tracing",
"windows-sys 0.60.2",
"zbus",
]
[[package]] [[package]]
name = "tauri-plugin-updater" name = "tauri-plugin-updater"
version = "2.10.1" version = "2.10.1"
@ -7163,7 +7179,7 @@ dependencies = [
"getrandom 0.4.2", "getrandom 0.4.2",
"once_cell", "once_cell",
"rustix 1.1.4", "rustix 1.1.4",
"windows-sys 0.59.0", "windows-sys 0.61.2",
] ]
[[package]] [[package]]

View File

@ -14,6 +14,7 @@ tauri-plugin-window-state = { version = "2.4.1" }
tauri-plugin-shell = "2.3.5" tauri-plugin-shell = "2.3.5"
tauri-plugin-dialog = "2.7.1" tauri-plugin-dialog = "2.7.1"
tauri-plugin-opener = "2.5.4" tauri-plugin-opener = "2.5.4"
tauri-plugin-single-instance = "2"
serde = { version = "1.0.228", features = ["derive"] } serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0.150" serde_json = "1.0.150"
keyring-core = "1.0.0" keyring-core = "1.0.0"

View File

@ -85,6 +85,26 @@ pub fn start_tauri() {
}); });
let app = tauri::Builder::default() let app = tauri::Builder::default()
.plugin(tauri_plugin_single_instance::init(|app, args, cwd| {
info!(Source = "Tauri"; "Prevented second app instance from starting. cwd='{cwd}', args={args:?}");
let Some(window) = app.get_webview_window("main") else {
warn!(Source = "Tauri"; "Second app instance was blocked, but the main window was not available for activation.");
return;
};
if let Err(error) = window.show() {
warn!(Source = "Tauri"; "Failed to show main window after second app start: {error}");
}
if let Err(error) = window.unminimize() {
warn!(Source = "Tauri"; "Failed to unminimize main window after second app start: {error}");
}
if let Err(error) = window.set_focus() {
warn!(Source = "Tauri"; "Failed to focus main window after second app start: {error}");
}
}))
.plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_shell::init())
.plugin(tauri_plugin_opener::init()) .plugin(tauri_plugin_opener::init())