From fe3739fdbbdd657d902f96eb1f76cb6a2e28c0eb Mon Sep 17 00:00:00 2001
From: jake
Date: Mon, 16 Mar 2026 23:26:27 +0000
Subject: [PATCH] fix(kon): task sidebar overlay, Parakeet model management,
conditional engine settings
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
TaskSidebar:
- Changed from flex layout member to fixed overlay with backdrop
- Click backdrop or press Escape to close
- Content no longer shrinks when sidebar opens — buttons stay accessible
- Positioned at z-50 over main content, top offset for titlebar
Settings — Parakeet model management:
- Added Parakeet model state: download, check, load status
- New downloadParakeet() and loadParakeet() functions
- Listens for parakeet-download-progress events
- Parakeet section shows download/load/status controls
Settings — conditional engine sections:
- Whisper model selector only shows when engine === "whisper"
- Parakeet model controls only show when engine === "parakeet"
- Cleaner UI — only active engine's options visible
Co-Authored-By: Claude Opus 4.6 (1M context)
---
src/lib/pages/SettingsPage.svelte | 132 ++++++++++++++++++++++++------
src/routes/+layout.svelte | 21 +++--
2 files changed, 122 insertions(+), 31 deletions(-)
diff --git a/src/lib/pages/SettingsPage.svelte b/src/lib/pages/SettingsPage.svelte
index 5c002cd..0352d6a 100644
--- a/src/lib/pages/SettingsPage.svelte
+++ b/src/lib/pages/SettingsPage.svelte
@@ -16,6 +16,14 @@
let downloadProgress = $state(0);
let unlisten = null;
+ // Parakeet state
+ let parakeetStatus = $state("Checking...");
+ let parakeetOk = $state(false);
+ let parakeetDownloaded = $state(false);
+ let parakeetDownloading = $state(false);
+ let parakeetProgress = $state(0);
+ let unlistenParakeet = null;
+
// Profiles & Templates
let showProfiles = $state(false);
let showTemplates = $state(false);
@@ -39,13 +47,27 @@
downloadedModels = await invoke("list_models");
} catch {}
+ // Parakeet status
+ try {
+ parakeetOk = await invoke("check_parakeet_engine");
+ parakeetDownloaded = await invoke("check_parakeet_model", { name: "ctc-int8" });
+ parakeetStatus = parakeetOk ? "Model loaded" : parakeetDownloaded ? "Downloaded (not loaded)" : "Not downloaded";
+ } catch {
+ parakeetStatus = "Engine not ready";
+ }
+
unlisten = await listen("model-download-progress", (event) => {
- downloadProgress = event.payload.progress;
+ downloadProgress = event.payload.percent || event.payload.progress || 0;
+ });
+
+ unlistenParakeet = await listen("parakeet-download-progress", (event) => {
+ parakeetProgress = event.payload.percent || event.payload.progress || 0;
});
});
onDestroy(() => {
if (unlisten) unlisten();
+ if (unlistenParakeet) unlistenParakeet();
});
// Auto-save on any change
@@ -105,6 +127,33 @@
Medium: "~1.5GB · best quality, slower",
};
+ async function downloadParakeet() {
+ parakeetDownloading = true;
+ parakeetProgress = 0;
+ try {
+ await invoke("download_parakeet_model", { name: "ctc-int8" });
+ parakeetDownloaded = true;
+ parakeetDownloading = false;
+ parakeetStatus = "Downloaded (not loaded)";
+ } catch {
+ parakeetDownloading = false;
+ parakeetStatus = "Download failed";
+ }
+ }
+
+ async function loadParakeet() {
+ parakeetStatus = "Loading...";
+ parakeetOk = false;
+ try {
+ await invoke("load_parakeet_model", { name: "ctc-int8" });
+ parakeetOk = true;
+ parakeetStatus = "Model loaded";
+ } catch (err) {
+ parakeetOk = false;
+ parakeetStatus = typeof err === "string" ? err : "Load failed";
+ }
+ }
+
// --- Profile management ---
function createProfile() {
if (!newProfileName.trim()) return;
@@ -180,33 +229,64 @@
-
-
-
Whisper Model
-
-
{modelDescriptions[settings.modelSize]}
+
+ {#if settings.engine === "whisper"}
+
+
Whisper Model
+
+
{modelDescriptions[settings.modelSize]}
-
-
- {#if isModelDownloaded(settings.modelSize)}
-
-
- Downloaded
-
-
- {:else if downloadingModel === settings.modelSize.toLowerCase()}
-
{downloadProgress}% downloading...
- {:else}
-
- {/if}
+
+ {#if isModelDownloaded(settings.modelSize)}
+
+
+ Downloaded
+
+
+ {:else if downloadingModel === settings.modelSize.toLowerCase()}
+ {downloadProgress}% downloading...
+ {:else}
+
+ {/if}
+
-
+ {:else}
+
+
Parakeet Model
+
Parakeet CTC 0.6B (int8) — ~613MB, near-instant transcription
+
+
+ {#if parakeetOk}
+
+
+ Model loaded
+
+ {:else if parakeetDownloaded}
+
+
+ Downloaded
+
+
+ {:else if parakeetDownloading}
+ {parakeetProgress}% downloading...
+ {:else}
+
+ {/if}
+
+
+ {/if}
diff --git a/src/routes/+layout.svelte b/src/routes/+layout.svelte
index f1d0e64..68a50cd 100644
--- a/src/routes/+layout.svelte
+++ b/src/routes/+layout.svelte
@@ -98,7 +98,7 @@
});
-
+
{ if (e.key === "Escape" && page.taskSidebarOpen) page.taskSidebarOpen = false; }} />
{#if page.recording}
-
+
{#if page.current !== "first-run"}
{/if}
{@render children()}
- {#if page.taskSidebarOpen && page.current !== "first-run"}
-
- {/if}
+
+
+ {#if page.taskSidebarOpen && page.current !== "first-run" && !isSecondaryWindow}
+
+
+
+
+
+
+ {/if}
{/if}