From 1119f6c3cf421da2f2db92873efae8135c76b678 Mon Sep 17 00:00:00 2001
From: HsiangNianian <i@jyunko.cn>
Date: Fri, 16 Jan 2026 18:38:47 +0800
Subject: feat: enhance Java version management for Minecraft versions

Added functionality to determine and validate the required Java version for Minecraft versions, including checks for compatibility with older versions. Implemented event emissions for version installation and deletion, and updated the UI to reflect Java version requirements and installation status. Improved version metadata handling and added support for deleting versions.
---
 ui/src/components/ModLoaderSelector.svelte | 38 +++++++++++++++++-------------
 1 file changed, 22 insertions(+), 16 deletions(-)

(limited to 'ui/src/components/ModLoaderSelector.svelte')

diff --git a/ui/src/components/ModLoaderSelector.svelte b/ui/src/components/ModLoaderSelector.svelte
index e9d147b..34f6f2e 100644
--- a/ui/src/components/ModLoaderSelector.svelte
+++ b/ui/src/components/ModLoaderSelector.svelte
@@ -291,7 +291,12 @@
         
     {:else if selectedLoader === "fabric"}
         <div class="space-y-4 animate-in fade-in slide-in-from-bottom-2 duration-300">
-        <div>
+        {#if fabricLoaders.length === 0}
+            <div class="text-center p-4 text-sm text-zinc-500 italic">
+            No Fabric versions available for {selectedGameVersion}
+            </div>
+        {:else}
+            <div>
             <label for="fabric-loader-select" class="block text-[10px] uppercase font-bold text-zinc-500 mb-2"
             >Loader Version</label
             >
@@ -339,21 +344,22 @@
                     </div>
                 {/if}
             </div>
-        </div>
-        
-        <button
-            class="w-full bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed text-white py-2.5 px-4 rounded-sm font-bold text-sm transition-all flex items-center justify-center gap-2"
-            onclick={installModLoader}
-            disabled={isInstalling || !selectedFabricLoader}
-        >
-            {#if isInstalling}
-                <Loader2 class="animate-spin" size={16} />
-                Installing...
-            {:else}
-                <Download size={16} />
-                Install Fabric {selectedFabricLoader}
-            {/if}
-        </button>
+            </div>
+            
+            <button
+                class="w-full bg-indigo-600 hover:bg-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed text-white py-2.5 px-4 rounded-sm font-bold text-sm transition-all flex items-center justify-center gap-2"
+                onclick={installModLoader}
+                disabled={isInstalling || !selectedFabricLoader}
+            >
+                {#if isInstalling}
+                    <Loader2 class="animate-spin" size={16} />
+                    Installing...
+                {:else}
+                    <Download size={16} />
+                    Install Fabric {selectedFabricLoader}
+                {/if}
+            </button>
+        {/if}
         </div>
         
     {:else if selectedLoader === "forge"}
-- 
cgit v1.2.3-70-g09d2


From 743401f15199a116b1777bced843c774c5a59fba Mon Sep 17 00:00:00 2001
From: HsiangNianian <i@jyunko.cn>
Date: Fri, 16 Jan 2026 20:20:19 +0800
Subject: feat: add InstancesView component and integrate instance management
 into the UI

Introduced a new InstancesView component for managing game instances, allowing users to create, edit, delete, and duplicate instances. Updated the App.svelte to include the InstancesView and modified various components to ensure instance selection is handled correctly. Enhanced the ModLoaderSelector and VersionsView to check for active instances before performing actions. Updated the Sidebar to include navigation to the new InstancesView.
---
 ui/src/App.svelte                          |   5 +
 ui/src/components/BottomBar.svelte         |  10 +-
 ui/src/components/InstancesView.svelte     | 331 +++++++++++++++++++++++++++++
 ui/src/components/ModLoaderSelector.svelte |  18 +-
 ui/src/components/Sidebar.svelte           |   3 +-
 ui/src/components/VersionsView.svelte      |  14 +-
 6 files changed, 376 insertions(+), 5 deletions(-)
 create mode 100644 ui/src/components/InstancesView.svelte

(limited to 'ui/src/components/ModLoaderSelector.svelte')

diff --git a/ui/src/App.svelte b/ui/src/App.svelte
index 2b78892..127bbea 100644
--- a/ui/src/App.svelte
+++ b/ui/src/App.svelte
@@ -11,12 +11,14 @@
   import ParticleBackground from "./components/ParticleBackground.svelte";
   import SettingsView from "./components/SettingsView.svelte";
   import AssistantView from "./components/AssistantView.svelte";
+  import InstancesView from "./components/InstancesView.svelte";
   import Sidebar from "./components/Sidebar.svelte";
   import StatusToast from "./components/StatusToast.svelte";
   import VersionsView from "./components/VersionsView.svelte";
 // Stores
   import { authState } from "./stores/auth.svelte";
   import { gameState } from "./stores/game.svelte";
+  import { instancesState } from "./stores/instances.svelte";
   import { settingsState } from "./stores/settings.svelte";
   import { uiState } from "./stores/ui.svelte";
   import { logsState } from "./stores/logs.svelte";
@@ -40,6 +42,7 @@
     await settingsState.loadSettings();
     logsState.init();
     await settingsState.detectJava();
+    await instancesState.loadInstances();
     gameState.loadVersions();
     getVersion().then((v) => (uiState.appVersion = v));
     window.addEventListener("mousemove", handleMouseMove);
@@ -113,6 +116,8 @@
           <div class="flex-1 relative overflow-hidden">
              {#if uiState.currentView === "home"}
                <HomeView mouseX={mouseX} mouseY={mouseY} />
+             {:else if uiState.currentView === "instances"}
+               <InstancesView />
              {:else if uiState.currentView === "versions"}
                <VersionsView />
              {:else if uiState.currentView === "settings"}
diff --git a/ui/src/components/BottomBar.svelte b/ui/src/components/BottomBar.svelte
index 8a6b7ff..19cf35d 100644
--- a/ui/src/components/BottomBar.svelte
+++ b/ui/src/components/BottomBar.svelte
@@ -4,6 +4,7 @@
   import { authState } from "../stores/auth.svelte";
   import { gameState } from "../stores/game.svelte";
   import { uiState } from "../stores/ui.svelte";
+  import { instancesState } from "../stores/instances.svelte";
   import { Terminal, ChevronDown, Play, User, Check } from 'lucide-svelte';
 
   interface InstalledVersion {
@@ -44,9 +45,16 @@
   }
 
   async function loadInstalledVersions() {
+    if (!instancesState.activeInstanceId) {
+      installedVersions = [];
+      isLoadingVersions = false;
+      return;
+    }
     isLoadingVersions = true;
     try {
-      installedVersions = await invoke<InstalledVersion[]>("list_installed_versions");
+      installedVersions = await invoke<InstalledVersion[]>("list_installed_versions", {
+        instanceId: instancesState.activeInstanceId,
+      });
       // If no version is selected but we have installed versions, select the first one
       if (!gameState.selectedVersion && installedVersions.length > 0) {
         gameState.selectedVersion = installedVersions[0].id;
diff --git a/ui/src/components/InstancesView.svelte b/ui/src/components/InstancesView.svelte
new file mode 100644
index 0000000..a4881e6
--- /dev/null
+++ b/ui/src/components/InstancesView.svelte
@@ -0,0 +1,331 @@
+<script lang="ts">
+  import { onMount } from "svelte";
+  import { instancesState } from "../stores/instances.svelte";
+  import { Plus, Trash2, Edit2, Copy, Check, X } from "lucide-svelte";
+  import type { Instance } from "../types";
+
+  let showCreateModal = $state(false);
+  let showEditModal = $state(false);
+  let showDeleteConfirm = $state(false);
+  let showDuplicateModal = $state(false);
+  let selectedInstance: Instance | null = $state(null);
+  let newInstanceName = $state("");
+  let duplicateName = $state("");
+
+  onMount(() => {
+    instancesState.loadInstances();
+  });
+
+  function handleCreate() {
+    newInstanceName = "";
+    showCreateModal = true;
+  }
+
+  function handleEdit(instance: Instance) {
+    selectedInstance = instance;
+    newInstanceName = instance.name;
+    showEditModal = true;
+  }
+
+  function handleDelete(instance: Instance) {
+    selectedInstance = instance;
+    showDeleteConfirm = true;
+  }
+
+  function handleDuplicate(instance: Instance) {
+    selectedInstance = instance;
+    duplicateName = `${instance.name} (Copy)`;
+    showDuplicateModal = true;
+  }
+
+  async function confirmCreate() {
+    if (!newInstanceName.trim()) return;
+    await instancesState.createInstance(newInstanceName.trim());
+    showCreateModal = false;
+    newInstanceName = "";
+  }
+
+  async function confirmEdit() {
+    if (!selectedInstance || !newInstanceName.trim()) return;
+    await instancesState.updateInstance({
+      ...selectedInstance,
+      name: newInstanceName.trim(),
+    });
+    showEditModal = false;
+    selectedInstance = null;
+    newInstanceName = "";
+  }
+
+  async function confirmDelete() {
+    if (!selectedInstance) return;
+    await instancesState.deleteInstance(selectedInstance.id);
+    showDeleteConfirm = false;
+    selectedInstance = null;
+  }
+
+  async function confirmDuplicate() {
+    if (!selectedInstance || !duplicateName.trim()) return;
+    await instancesState.duplicateInstance(selectedInstance.id, duplicateName.trim());
+    showDuplicateModal = false;
+    selectedInstance = null;
+    duplicateName = "";
+  }
+
+  function formatDate(timestamp: number): string {
+    return new Date(timestamp * 1000).toLocaleDateString();
+  }
+
+  function formatLastPlayed(timestamp: number): string {
+    const date = new Date(timestamp * 1000);
+    const now = new Date();
+    const diff = now.getTime() - date.getTime();
+    const days = Math.floor(diff / (1000 * 60 * 60 * 24));
+    
+    if (days === 0) return "Today";
+    if (days === 1) return "Yesterday";
+    if (days < 7) return `${days} days ago`;
+    return date.toLocaleDateString();
+  }
+</script>
+
+<div class="h-full flex flex-col gap-4 p-6 overflow-y-auto">
+  <div class="flex items-center justify-between">
+    <h1 class="text-2xl font-bold text-gray-900 dark:text-white">Instances</h1>
+    <button
+      onclick={handleCreate}
+      class="flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors"
+    >
+      <Plus size={18} />
+      Create Instance
+    </button>
+  </div>
+
+  {#if instancesState.instances.length === 0}
+    <div class="flex-1 flex items-center justify-center">
+      <div class="text-center text-gray-500 dark:text-gray-400">
+        <p class="text-lg mb-2">No instances yet</p>
+        <p class="text-sm">Create your first instance to get started</p>
+      </div>
+    </div>
+  {:else}
+    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
+      {#each instancesState.instances as instance (instance.id)}
+        <div
+          class="relative p-4 bg-gray-100 dark:bg-gray-800 rounded-lg border-2 transition-all cursor-pointer hover:border-blue-500 {instancesState.activeInstanceId === instance.id
+            ? 'border-blue-500'
+            : 'border-transparent'}"
+          onclick={() => instancesState.setActiveInstance(instance.id)}
+        >
+          {#if instancesState.activeInstanceId === instance.id}
+            <div class="absolute top-2 right-2">
+              <div class="w-3 h-3 bg-blue-500 rounded-full"></div>
+            </div>
+          {/if}
+
+          <div class="flex items-start justify-between mb-2">
+            <h3 class="text-lg font-semibold text-gray-900 dark:text-white">
+              {instance.name}
+            </h3>
+            <div class="flex gap-1">
+              <button
+                onclick={(e) => {
+                  e.stopPropagation();
+                  handleEdit(instance);
+                }}
+                class="p-1 hover:bg-gray-200 dark:hover:bg-gray-700 rounded transition-colors"
+                title="Edit"
+              >
+                <Edit2 size={16} class="text-gray-600 dark:text-gray-400" />
+              </button>
+              <button
+                onclick={(e) => {
+                  e.stopPropagation();
+                  handleDuplicate(instance);
+                }}
+                class="p-1 hover:bg-gray-200 dark:hover:bg-gray-700 rounded transition-colors"
+                title="Duplicate"
+              >
+                <Copy size={16} class="text-gray-600 dark:text-gray-400" />
+              </button>
+              <button
+                onclick={(e) => {
+                  e.stopPropagation();
+                  handleDelete(instance);
+                }}
+                class="p-1 hover:bg-gray-200 dark:hover:bg-gray-700 rounded transition-colors"
+                title="Delete"
+              >
+                <Trash2 size={16} class="text-red-600 dark:text-red-400" />
+              </button>
+            </div>
+          </div>
+
+          <div class="space-y-1 text-sm text-gray-600 dark:text-gray-400">
+            {#if instance.version_id}
+              <p>Version: <span class="font-medium">{instance.version_id}</span></p>
+            {:else}
+              <p class="text-gray-400">No version selected</p>
+            {/if}
+
+            {#if instance.mod_loader && instance.mod_loader !== "vanilla"}
+              <p>
+                Mod Loader: <span class="font-medium capitalize">{instance.mod_loader}</span>
+                {#if instance.mod_loader_version}
+                  <span class="text-gray-500">({instance.mod_loader_version})</span>
+                {/if}
+              </p>
+            {/if}
+
+            <p>Created: {formatDate(instance.created_at)}</p>
+
+            {#if instance.last_played}
+              <p>Last played: {formatLastPlayed(instance.last_played)}</p>
+            {/if}
+          </div>
+
+          {#if instance.notes}
+            <p class="mt-2 text-sm text-gray-500 dark:text-gray-500 italic">
+              {instance.notes}
+            </p>
+          {/if}
+        </div>
+      {/each}
+    </div>
+  {/if}
+</div>
+
+<!-- Create Modal -->
+{#if showCreateModal}
+  <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
+    <div class="bg-white dark:bg-gray-800 rounded-lg p-6 w-96">
+      <h2 class="text-xl font-bold mb-4 text-gray-900 dark:text-white">Create Instance</h2>
+      <input
+        type="text"
+        bind:value={newInstanceName}
+        placeholder="Instance name"
+        class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white mb-4"
+        onkeydown={(e) => e.key === "Enter" && confirmCreate()}
+        autofocus
+      />
+      <div class="flex gap-2 justify-end">
+        <button
+          onclick={() => {
+            showCreateModal = false;
+            newInstanceName = "";
+          }}
+          class="px-4 py-2 bg-gray-200 dark:bg-gray-700 text-gray-900 dark:text-white rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors"
+        >
+          Cancel
+        </button>
+        <button
+          onclick={confirmCreate}
+          disabled={!newInstanceName.trim()}
+          class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
+        >
+          Create
+        </button>
+      </div>
+    </div>
+  </div>
+{/if}
+
+<!-- Edit Modal -->
+{#if showEditModal && selectedInstance}
+  <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
+    <div class="bg-white dark:bg-gray-800 rounded-lg p-6 w-96">
+      <h2 class="text-xl font-bold mb-4 text-gray-900 dark:text-white">Edit Instance</h2>
+      <input
+        type="text"
+        bind:value={newInstanceName}
+        placeholder="Instance name"
+        class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white mb-4"
+        onkeydown={(e) => e.key === "Enter" && confirmEdit()}
+        autofocus
+      />
+      <div class="flex gap-2 justify-end">
+        <button
+          onclick={() => {
+            showEditModal = false;
+            selectedInstance = null;
+            newInstanceName = "";
+          }}
+          class="px-4 py-2 bg-gray-200 dark:bg-gray-700 text-gray-900 dark:text-white rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors"
+        >
+          Cancel
+        </button>
+        <button
+          onclick={confirmEdit}
+          disabled={!newInstanceName.trim()}
+          class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
+        >
+          Save
+        </button>
+      </div>
+    </div>
+  </div>
+{/if}
+
+<!-- Delete Confirmation -->
+{#if showDeleteConfirm && selectedInstance}
+  <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
+    <div class="bg-white dark:bg-gray-800 rounded-lg p-6 w-96">
+      <h2 class="text-xl font-bold mb-4 text-red-600 dark:text-red-400">Delete Instance</h2>
+      <p class="mb-4 text-gray-700 dark:text-gray-300">
+        Are you sure you want to delete "{selectedInstance.name}"? This action cannot be undone and will delete all game data for this instance.
+      </p>
+      <div class="flex gap-2 justify-end">
+        <button
+          onclick={() => {
+            showDeleteConfirm = false;
+            selectedInstance = null;
+          }}
+          class="px-4 py-2 bg-gray-200 dark:bg-gray-700 text-gray-900 dark:text-white rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors"
+        >
+          Cancel
+        </button>
+        <button
+          onclick={confirmDelete}
+          class="px-4 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors"
+        >
+          Delete
+        </button>
+      </div>
+    </div>
+  </div>
+{/if}
+
+<!-- Duplicate Modal -->
+{#if showDuplicateModal && selectedInstance}
+  <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
+    <div class="bg-white dark:bg-gray-800 rounded-lg p-6 w-96">
+      <h2 class="text-xl font-bold mb-4 text-gray-900 dark:text-white">Duplicate Instance</h2>
+      <input
+        type="text"
+        bind:value={duplicateName}
+        placeholder="New instance name"
+        class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-700 text-gray-900 dark:text-white mb-4"
+        onkeydown={(e) => e.key === "Enter" && confirmDuplicate()}
+        autofocus
+      />
+      <div class="flex gap-2 justify-end">
+        <button
+          onclick={() => {
+            showDuplicateModal = false;
+            selectedInstance = null;
+            duplicateName = "";
+          }}
+          class="px-4 py-2 bg-gray-200 dark:bg-gray-700 text-gray-900 dark:text-white rounded-lg hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors"
+        >
+          Cancel
+        </button>
+        <button
+          onclick={confirmDuplicate}
+          disabled={!duplicateName.trim()}
+          class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
+        >
+          Duplicate
+        </button>
+      </div>
+    </div>
+  </div>
+{/if}
diff --git a/ui/src/components/ModLoaderSelector.svelte b/ui/src/components/ModLoaderSelector.svelte
index 34f6f2e..50caa8c 100644
--- a/ui/src/components/ModLoaderSelector.svelte
+++ b/ui/src/components/ModLoaderSelector.svelte
@@ -9,6 +9,7 @@
   } from "../types";
   import { Loader2, Download, AlertCircle, Check, ChevronDown, CheckCircle } from 'lucide-svelte';
   import { logsState } from "../stores/logs.svelte";
+  import { instancesState } from "../stores/instances.svelte";
 
   interface Props {
     selectedGameVersion: string;
@@ -52,12 +53,13 @@
   });
 
   async function checkInstallStatus() {
-    if (!selectedGameVersion) {
+    if (!selectedGameVersion || !instancesState.activeInstanceId) {
       isVersionInstalled = false;
       return;
     }
     try {
       isVersionInstalled = await invoke<boolean>("check_version_installed", {
+        instanceId: instancesState.activeInstanceId,
         versionId: selectedGameVersion,
       });
     } catch (e) {
@@ -112,8 +114,13 @@
     error = null;
     logsState.addLog("info", "Installer", `Starting installation of ${selectedGameVersion}...`);
 
+    if (!instancesState.activeInstanceId) {
+      error = "Please select an instance first";
+      return;
+    }
     try {
       await invoke("install_version", {
+        instanceId: instancesState.activeInstanceId,
         versionId: selectedGameVersion,
       });
       logsState.addLog("info", "Installer", `Successfully installed ${selectedGameVersion}`);
@@ -134,6 +141,12 @@
       return;
     }
 
+    if (!instancesState.activeInstanceId) {
+      error = "Please select an instance first";
+      isInstalling = false;
+      return;
+    }
+
     isInstalling = true;
     error = null;
 
@@ -142,6 +155,7 @@
       if (!isVersionInstalled) {
         logsState.addLog("info", "Installer", `Installing base game ${selectedGameVersion} first...`);
         await invoke("install_version", {
+          instanceId: instancesState.activeInstanceId,
           versionId: selectedGameVersion,
         });
         isVersionInstalled = true;
@@ -151,6 +165,7 @@
       if (selectedLoader === "fabric" && selectedFabricLoader) {
         logsState.addLog("info", "Installer", `Installing Fabric ${selectedFabricLoader} for ${selectedGameVersion}...`);
         const result = await invoke<any>("install_fabric", {
+          instanceId: instancesState.activeInstanceId,
           gameVersion: selectedGameVersion,
           loaderVersion: selectedFabricLoader,
         });
@@ -159,6 +174,7 @@
       } else if (selectedLoader === "forge" && selectedForgeVersion) {
         logsState.addLog("info", "Installer", `Installing Forge ${selectedForgeVersion} for ${selectedGameVersion}...`);
         const result = await invoke<any>("install_forge", {
+          instanceId: instancesState.activeInstanceId,
           gameVersion: selectedGameVersion,
           forgeVersion: selectedForgeVersion,
         });
diff --git a/ui/src/components/Sidebar.svelte b/ui/src/components/Sidebar.svelte
index 3d36f89..83f4ac6 100644
--- a/ui/src/components/Sidebar.svelte
+++ b/ui/src/components/Sidebar.svelte
@@ -1,6 +1,6 @@
 <script lang="ts">
   import { uiState } from '../stores/ui.svelte';
-  import { Home, Package, Settings, Bot } from 'lucide-svelte';
+  import { Home, Package, Settings, Bot, Folder } from 'lucide-svelte';
 </script>
 
 <aside
@@ -76,6 +76,7 @@
     {/snippet}
 
     {@render navItem('home', Home, 'Overview')}
+    {@render navItem('instances', Folder, 'Instances')}
     {@render navItem('versions', Package, 'Versions')}
     {@render navItem('guide', Bot, 'Assistant')}
     {@render navItem('settings', Settings, 'Settings')}
diff --git a/ui/src/components/VersionsView.svelte b/ui/src/components/VersionsView.svelte
index 2e8b028..d4d36d5 100644
--- a/ui/src/components/VersionsView.svelte
+++ b/ui/src/components/VersionsView.svelte
@@ -2,6 +2,7 @@
   import { invoke } from "@tauri-apps/api/core";
   import { listen, type UnlistenFn } from "@tauri-apps/api/event";
   import { gameState } from "../stores/game.svelte";
+  import { instancesState } from "../stores/instances.svelte";
   import ModLoaderSelector from "./ModLoaderSelector.svelte";
 
   let searchQuery = $state("");
@@ -18,11 +19,17 @@
 
   // Load installed modded versions with Java version info (both Fabric and Forge)
   async function loadInstalledModdedVersions() {
+    if (!instancesState.activeInstanceId) {
+      installedFabricVersions = [];
+      isLoadingModded = false;
+      return;
+    }
     isLoadingModded = true;
     try {
       // Get all installed versions and filter for modded ones (Fabric and Forge)
       const allInstalled = await invoke<Array<{ id: string; type: string }>>(
-        "list_installed_versions"
+        "list_installed_versions",
+        { instanceId: instancesState.activeInstanceId }
       );
       
       // Filter for Fabric and Forge versions
@@ -36,7 +43,10 @@
           try {
             const javaVersion = await invoke<number | null>(
               "get_version_java_version",
-              { versionId: id }
+              {
+                instanceId: instancesState.activeInstanceId!,
+                versionId: id,
+              }
             );
             return {
               id,
-- 
cgit v1.2.3-70-g09d2

