From 58f87277ef0be0ac95ebe60a045804a47f3c36e9 Mon Sep 17 00:00:00 2001 From: Thorsten Sommer Date: Sun, 19 Jul 2026 14:53:16 +0200 Subject: [PATCH] Prepared Linux packaging and Flatpak integration (#870) --- .github/workflows/build-and-release.yml | 29 ++-- runtime/Cargo.lock | 132 +++++++++++++++++- runtime/Cargo.toml | 2 +- .../linux/org.mindworkai.AIStudio.desktop | 14 ++ .../org.mindworkai.AIStudio.metainfo.xml | 111 +++++++++++++++ runtime/tauri.linux.conf.json | 3 + 6 files changed, 275 insertions(+), 16 deletions(-) create mode 100644 runtime/packaging/linux/org.mindworkai.AIStudio.desktop create mode 100644 runtime/packaging/linux/org.mindworkai.AIStudio.metainfo.xml create mode 100644 runtime/tauri.linux.conf.json diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 6ac6550b..1e44fe58 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -261,7 +261,10 @@ jobs: with: ref: ${{ env.AI_STUDIO_COMMIT }} path: ai-studio - sparse-checkout: metadata.txt + sparse-checkout: | + metadata.txt + runtime/packaging/linux/org.mindworkai.AIStudio.desktop + runtime/packaging/linux/org.mindworkai.AIStudio.metainfo.xml sparse-checkout-cone-mode: false - name: Checkout Flatpak repository @@ -329,8 +332,12 @@ jobs: test "$release_version" = "${AI_STUDIO_TAG#v}" [[ "$release_timestamp" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}[[:space:]][0-9]{2}:[0-9]{2}:[0-9]{2}[[:space:]]UTC$ ]] - python3 ./update-metainfo.py "$release_version" "$release_date" - python3 ./update-metainfo.py --check "$release_version" "$release_date" + test -s ../ai-studio/runtime/packaging/linux/org.mindworkai.AIStudio.desktop + python3 ./update-metainfo.py \ + --check \ + --metainfo ../ai-studio/runtime/packaging/linux/org.mindworkai.AIStudio.metainfo.xml \ + "$release_version" \ + "$release_date" pdfium_base_url="https://github.com/bblanchon/pdfium-binaries/releases/download/chromium%2F${PDFIUM_CHROMIUM_REVISION}" pdfium_x64_url="${pdfium_base_url}/pdfium-linux-x64.tgz" @@ -353,16 +360,16 @@ jobs: (.modules[] | select(.name == "mind-work-ai-studio").sources[] | select(.type == "archive" and .only-arches[0] == "x86_64").sha256) = strenv(PDFIUM_X64_SHA256) | (.modules[] | select(.name == "mind-work-ai-studio").sources[] | select(.type == "archive" and .only-arches[0] == "aarch64").url) = strenv(PDFIUM_ARM64_URL) | (.modules[] | select(.name == "mind-work-ai-studio").sources[] | select(.type == "archive" and .only-arches[0] == "aarch64").sha256) = strenv(PDFIUM_ARM64_SHA256) - ' org.MindWorkAI.AIStudio.yml + ' org.mindworkai.AIStudio.yml ./update-dependencies - test "$(yq -r '(.modules[] | select(.name == "mind-work-ai-studio")).sources[0].tag' org.MindWorkAI.AIStudio.yml)" = "$AI_STUDIO_TAG" - test "$(yq -r '(.modules[] | select(.name == "mind-work-ai-studio")).sources[0].commit' org.MindWorkAI.AIStudio.yml)" = "$AI_STUDIO_COMMIT" - test "$(yq -r '(.modules[] | select(.name == "mind-work-ai-studio")).sources[] | select(.type == "archive" and .only-arches[0] == "x86_64").url' org.MindWorkAI.AIStudio.yml)" = "$PDFIUM_X64_URL" - test "$(yq -r '(.modules[] | select(.name == "mind-work-ai-studio")).sources[] | select(.type == "archive" and .only-arches[0] == "x86_64").sha256' org.MindWorkAI.AIStudio.yml)" = "$PDFIUM_X64_SHA256" - test "$(yq -r '(.modules[] | select(.name == "mind-work-ai-studio")).sources[] | select(.type == "archive" and .only-arches[0] == "aarch64").url' org.MindWorkAI.AIStudio.yml)" = "$PDFIUM_ARM64_URL" - test "$(yq -r '(.modules[] | select(.name == "mind-work-ai-studio")).sources[] | select(.type == "archive" and .only-arches[0] == "aarch64").sha256' org.MindWorkAI.AIStudio.yml)" = "$PDFIUM_ARM64_SHA256" + test "$(yq -r '(.modules[] | select(.name == "mind-work-ai-studio")).sources[0].tag' org.mindworkai.AIStudio.yml)" = "$AI_STUDIO_TAG" + test "$(yq -r '(.modules[] | select(.name == "mind-work-ai-studio")).sources[0].commit' org.mindworkai.AIStudio.yml)" = "$AI_STUDIO_COMMIT" + test "$(yq -r '(.modules[] | select(.name == "mind-work-ai-studio")).sources[] | select(.type == "archive" and .only-arches[0] == "x86_64").url' org.mindworkai.AIStudio.yml)" = "$PDFIUM_X64_URL" + test "$(yq -r '(.modules[] | select(.name == "mind-work-ai-studio")).sources[] | select(.type == "archive" and .only-arches[0] == "x86_64").sha256' org.mindworkai.AIStudio.yml)" = "$PDFIUM_X64_SHA256" + test "$(yq -r '(.modules[] | select(.name == "mind-work-ai-studio")).sources[] | select(.type == "archive" and .only-arches[0] == "aarch64").url' org.mindworkai.AIStudio.yml)" = "$PDFIUM_ARM64_URL" + test "$(yq -r '(.modules[] | select(.name == "mind-work-ai-studio")).sources[] | select(.type == "archive" and .only-arches[0] == "aarch64").sha256' org.mindworkai.AIStudio.yml)" = "$PDFIUM_ARM64_SHA256" for generated_source in cargo-sources.json dotnet-sources.json tauri-cli-sources.json; do test -s "$generated_source" @@ -385,7 +392,7 @@ jobs: branch="sync/ai-studio-${AI_STUDIO_TAG}" git checkout -B "$branch" - git add org.MindWorkAI.AIStudio.yml org.MindWorkAI.AIStudio.metainfo.xml cargo-sources.json dotnet-sources.json tauri-cli-sources.json + git add org.mindworkai.AIStudio.yml cargo-sources.json dotnet-sources.json tauri-cli-sources.json if git diff --cached --quiet; then echo "Flatpak repository is already synced for ${AI_STUDIO_TAG}." diff --git a/runtime/Cargo.lock b/runtime/Cargo.lock index 8e98f77b..f9c42d98 100644 --- a/runtime/Cargo.lock +++ b/runtime/Cargo.lock @@ -242,6 +242,27 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +[[package]] +name = "ashpd" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f3f79755c74fd155000314eb349864caa787c6592eace6c6882dad873d9c39" +dependencies = [ + "enumflags2", + "futures-channel", + "futures-util", + "rand 0.9.4", + "raw-window-handle", + "serde", + "serde_repr", + "tokio", + "url", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "zbus", +] + [[package]] name = "ashpd" version = "0.13.12" @@ -1890,6 +1911,15 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading 0.7.4", +] + [[package]] name = "dlopen2" version = "0.8.2" @@ -1940,6 +1970,12 @@ dependencies = [ "tendril", ] +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "dpi" version = "0.1.2" @@ -4129,7 +4165,7 @@ dependencies = [ "aes 0.9.1", "apple-native-keyring-store", "arboard", - "ashpd", + "ashpd 0.13.12", "async-stream", "axum", "axum-server", @@ -5194,6 +5230,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "pollster" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" + [[package]] name = "portable-atomic" version = "1.13.1" @@ -5459,6 +5501,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "quick-xml" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" +dependencies = [ + "memchr", +] + [[package]] name = "quick-xml" version = "0.41.0" @@ -5846,18 +5897,18 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a15ad77d9e70a92437d8f74c35d99b4e4691128df018833e99f90bcd36152672" dependencies = [ + "ashpd 0.11.1", "block2 0.6.2", "dispatch2", - "glib-sys", - "gobject-sys", - "gtk-sys", "js-sys", "log", "objc2 0.6.4", "objc2-app-kit", "objc2-core-foundation", "objc2-foundation 0.3.2", + "pollster", "raw-window-handle", + "urlencoding", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -6201,6 +6252,12 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -8229,6 +8286,12 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "urlpattern" version = "0.3.0" @@ -8567,6 +8630,66 @@ dependencies = [ "semver", ] +[[package]] +name = "wayland-backend" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee64194ccd96bf648f42a65a7e589547096dfa702f7cadef84347b66ad164f9" +dependencies = [ + "cc", + "downcast-rs", + "rustix 1.1.4", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e6faa537fbb6c186cb9f1d41f2f811a4120d1b57ec61f50da451a0c5122bec" +dependencies = [ + "bitflags 2.11.1", + "rustix 1.1.4", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols" +version = "0.32.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baeda9ffbcfc8cd6ddaade385eaf2393bd2115a69523c735f12242353c3df4f3" +dependencies = [ + "bitflags 2.11.1", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5423e94b6a63e68e439803a3e153a9252d5ead12fd853334e2ad33997e3889e3" +dependencies = [ + "proc-macro2", + "quick-xml 0.38.4", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6dbfc3ac5ef974c92a2235805cc0114033018ae1290a72e474aa8b28cbbdfd" +dependencies = [ + "dlib", + "log", + "pkg-config", +] + [[package]] name = "web-sys" version = "0.3.97" @@ -9931,6 +10054,7 @@ dependencies = [ "endi", "enumflags2", "serde", + "url", "winnow 1.0.2", "zvariant_derive", "zvariant_utils", diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 46501799..dce0b5c6 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -12,7 +12,7 @@ tauri-build = { version = "2.6.3", features = [] } tauri = { version = "2.11.5", features = [] } tauri-plugin-window-state = { version = "2.4.1" } tauri-plugin-shell = "2.3.5" -tauri-plugin-dialog = "2.7.1" +tauri-plugin-dialog = { version = "2.7.1", default-features = false, features = ["xdg-portal"] } tauri-plugin-opener = "2.5.4" tauri-plugin-single-instance = "2" serde = { version = "1.0.228", features = ["derive"] } diff --git a/runtime/packaging/linux/org.mindworkai.AIStudio.desktop b/runtime/packaging/linux/org.mindworkai.AIStudio.desktop new file mode 100644 index 00000000..dda355f7 --- /dev/null +++ b/runtime/packaging/linux/org.mindworkai.AIStudio.desktop @@ -0,0 +1,14 @@ +[Desktop Entry] +Type=Application +Version=1.5 +Name=MindWork AI Studio +GenericName=AI Studio +Comment=MindWork AI Studio is a free, independent cross-platform desktop app for local and cloud LLMs across providers, built to democratize AI access. +Keywords=AI;LLM;Assistant; +Exec=mind-work-ai-studio +TryExec=mind-work-ai-studio +Icon=org.mindworkai.AIStudio +Categories=Science;Utility;Office; +SingleMainWindow=true +DBusActivatable=false +StartupWMClass=org.mindworkai.AIStudio \ No newline at end of file diff --git a/runtime/packaging/linux/org.mindworkai.AIStudio.metainfo.xml b/runtime/packaging/linux/org.mindworkai.AIStudio.metainfo.xml new file mode 100644 index 00000000..f0ce4e31 --- /dev/null +++ b/runtime/packaging/linux/org.mindworkai.AIStudio.metainfo.xml @@ -0,0 +1,111 @@ + + + org.mindworkai.AIStudio + MindWork AI Studio + FSL-1.1-MIT + MIT + + MindWork AI Studio is a free, independent cross-platform desktop app for local and cloud LLMs across providers, built to democratize AI access. + + MindWork AI Community + + + +

+ MindWork AI Studio is a free desktop app for macOS, Windows, and Linux. It provides a unified user interface + for interaction with Large Language Models (LLM). AI Studio also offers so-called assistants, where prompting + is not necessary. You can think of AI Studio like an email program: you bring your own API key for the LLM of + your choice and can then use these AI systems with AI Studio. +

+

Key advantages:

+
    +
  • + Free of charge: The app is free to use, both for personal and commercial purposes. +
  • +
  • + Democratization of AI: MindWork AI Studio runs even on low-cost hardware, including + computers such as Raspberry Pi. This makes the app and its full feature set accessible + to people and families with limited budgets. You can start with local LLMs or use + affordable cloud models. +
  • +
  • + Independence: You are not tied to any single provider. Choose the providers that best + suit your needs, including OpenAI, Perplexity, Mistral, Anthropic, Google Gemini, xAI, + DeepSeek, Alibaba Cloud, OpenRouter, Hugging Face, Groq, Fireworks, Helmholtz, GWDG, + and self-hosted models. +
  • +
  • + Assistants: Use ready-made assistants for common business and other tasks without writing prompts yourself. +
  • +
  • + Unrestricted usage: Unlike services that impose limits after intensive use, MindWork + AI Studio lets you use provider APIs without restrictions imposed by the app. +
  • +
  • + Cost-effective: You only pay providers for what you use, which can be cheaper than a + monthly subscription when used infrequently. For intensive usage, API costs may be + higher, so you should monitor your provider accounts and use prepaid credit or cost + limits when available. +
  • +
  • + Privacy: Control which providers receive your data using provider confidence settings + and assign different protection levels to different tasks. +
  • +
  • + Flexibility: Choose the provider and model best suited to your current task. +
  • +
  • + No bloatware: The app requires little storage and memory and has minimal impact on + system resources and battery life. +
  • +
+
+ + org.mindworkai.AIStudio.desktop + + + Utility + Office + Science + + + + AI + Assistant + Privacy + + + https://mindworkai.org + https://github.com/MindWorkAI/AI-Studio/issues + https://github.com/MindWorkAI + https://github.com/MindWorkAI/AI-Studio#contributing-ov-file + https://github.com/MindWorkAI/AI-Studio + + + mind-work-ai-studio + + + + #b4bed5 + #707e99 + + + + + https://github.com/MindWorkAI/AI-Studio/blob/main/documentation/AI%20Studio%20Home.png?raw=true + Getting started + + + https://raw.githubusercontent.com/MindWorkAI/AI-Studio/refs/heads/main/documentation/AI%20Studio%20Assistants.png + Assistants + + + + + + +

Update

+
+
+
+
\ No newline at end of file diff --git a/runtime/tauri.linux.conf.json b/runtime/tauri.linux.conf.json new file mode 100644 index 00000000..a0486890 --- /dev/null +++ b/runtime/tauri.linux.conf.json @@ -0,0 +1,3 @@ +{ + "identifier": "org.mindworkai.AIStudio" +} \ No newline at end of file