chore: rebrand from Kon/Corbie to Magnotia

Replace all instances of the legacy product names "Kon" and "Corbie" with
"Magnotia" across user-facing copy, code identifiers, package names, bundle
ids, file paths, and documentation. Preserves the unrelated "konsole" (KDE
terminal) reference and the parent CORBEL company name.

- Renames 10 Rust crates (kon-* → magnotia-*) and the tauri binary
- Updates package.json, tauri.conf.json (productName + identifier)
- Renames CSS classes (kon-rh-* → magnotia-rh-*) and animations
- Renames brand and roadmap docs
- Regenerates Cargo.lock and package-lock.json

Verified: svelte-check passes; pure-rust crates compile under new names.
This commit is contained in:
Claude
2026-04-30 13:06:55 +00:00
parent 749403697a
commit 89c63891fa
186 changed files with 1297 additions and 1297 deletions

View File

@@ -2,9 +2,9 @@ use std::collections::HashSet;
use std::path::{Path, PathBuf};
use std::sync::{LazyLock, Mutex};
use kon_core::error::{KonError, Result};
use kon_core::model_registry::{find_model, ModelFile};
use kon_core::types::{DownloadProgress, ModelId};
use magnotia_core::error::{MagnotiaError, Result};
use magnotia_core::model_registry::{find_model, ModelFile};
use magnotia_core::types::{DownloadProgress, ModelId};
static ACTIVE_DOWNLOADS: LazyLock<Mutex<HashSet<String>>> =
LazyLock::new(|| Mutex::new(HashSet::new()));
@@ -18,9 +18,9 @@ impl DownloadReservation {
let id = id.as_str().to_string();
let mut active = ACTIVE_DOWNLOADS
.lock()
.map_err(|_| KonError::DownloadFailed("download lock poisoned".into()))?;
.map_err(|_| MagnotiaError::DownloadFailed("download lock poisoned".into()))?;
if !active.insert(id.clone()) {
return Err(KonError::DownloadFailed(format!(
return Err(MagnotiaError::DownloadFailed(format!(
"download already in progress for {id}"
)));
}
@@ -37,15 +37,15 @@ impl Drop for DownloadReservation {
}
/// Resolve the models storage directory.
/// Windows: %LOCALAPPDATA%/kon/models
/// Unix: ~/.kon/models
/// Windows: %LOCALAPPDATA%/magnotia/models
/// Unix: ~/.magnotia/models
pub fn models_dir() -> PathBuf {
kon_core::paths::app_paths().models_dir()
magnotia_core::paths::app_paths().models_dir()
}
/// Get the directory path where a specific model's files are stored.
pub fn model_dir(id: &ModelId) -> PathBuf {
kon_core::paths::app_paths().speech_model_dir(id)
magnotia_core::paths::app_paths().speech_model_dir(id)
}
/// Check whether all files for a model have been downloaded.
@@ -61,7 +61,7 @@ pub fn is_downloaded(id: &ModelId) -> bool {
/// List all downloaded model IDs.
pub fn list_downloaded() -> Vec<ModelId> {
kon_core::model_registry::all_models()
magnotia_core::model_registry::all_models()
.iter()
.filter(|m| is_downloaded(&m.id))
.map(|m| m.id.clone())
@@ -74,13 +74,13 @@ pub fn list_downloaded() -> Vec<ModelId> {
/// For files that declare a `sha256` checksum we validate an existing
/// complete file before skipping the download — a truncated or
/// tampered file gets redownloaded automatically (pattern ported from
/// `kon-llm`'s model_manager, item #8 in the Whisper ecosystem brief).
/// `magnotia-llm`'s model_manager, item #8 in the Whisper ecosystem brief).
pub async fn download(
id: &ModelId,
progress: impl Fn(DownloadProgress) + Send + 'static,
) -> Result<()> {
let _reservation = DownloadReservation::acquire(id)?;
let entry = find_model(id).ok_or_else(|| KonError::ModelNotFound(id.clone()))?;
let entry = find_model(id).ok_or_else(|| MagnotiaError::ModelNotFound(id.clone()))?;
let dir = model_dir(id);
std::fs::create_dir_all(&dir)?;
@@ -98,7 +98,7 @@ pub async fn download(
let _ = std::fs::remove_file(&dest);
}
Err(e) => {
return Err(KonError::DownloadFailed(format!(
return Err(MagnotiaError::DownloadFailed(format!(
"failed to verify existing {}: {e}",
file.filename
)));
@@ -113,10 +113,10 @@ pub async fn download(
}
fn verified_manifest_path(dir: &Path) -> PathBuf {
dir.join(".kon-verified")
dir.join(".magnotia-verified")
}
fn verified_manifest_matches(entry: &kon_core::model_registry::ModelEntry, dir: &Path) -> bool {
fn verified_manifest_matches(entry: &magnotia_core::model_registry::ModelEntry, dir: &Path) -> bool {
let manifest = match std::fs::read_to_string(verified_manifest_path(dir)) {
Ok(contents) => contents,
Err(_) => return false,
@@ -137,7 +137,7 @@ fn verified_manifest_matches(entry: &kon_core::model_registry::ModelEntry, dir:
}
fn write_verified_manifest(
entry: &kon_core::model_registry::ModelEntry,
entry: &magnotia_core::model_registry::ModelEntry,
dir: &Path,
) -> std::io::Result<()> {
let mut lines = Vec::with_capacity(entry.files.len() + 1);
@@ -193,7 +193,7 @@ async fn download_file(
let client = reqwest::Client::builder()
.connect_timeout(std::time::Duration::from_secs(30))
.build()
.map_err(|e| KonError::DownloadFailed(e.to_string()))?;
.map_err(|e| MagnotiaError::DownloadFailed(e.to_string()))?;
// Check for existing partial download (resume support)
let existing_bytes = if part_path.exists() {
@@ -212,12 +212,12 @@ async fn download_file(
let response = request
.send()
.await
.map_err(|e| KonError::DownloadFailed(e.to_string()))?;
.map_err(|e| MagnotiaError::DownloadFailed(e.to_string()))?;
// If we requested Range but the server returned 200 (full file), the
// server does not support resume. Rather than blindly appending a
// full file on top of our partial bytes (which would produce a
// corrupt result), restart cleanly. This mirrors the kon-llm
// corrupt result), restart cleanly. This mirrors the magnotia-llm
// ResumeUnsupported branch — item #8 of the brief.
//
// For the non-resume path, we still have to validate the status:
@@ -234,14 +234,14 @@ async fn download_file(
false
}
other => {
return Err(KonError::DownloadFailed(format!(
return Err(MagnotiaError::DownloadFailed(format!(
"resume request returned unexpected status {other}"
)));
}
}
} else {
if !response.status().is_success() {
return Err(KonError::DownloadFailed(format!(
return Err(MagnotiaError::DownloadFailed(format!(
"download returned HTTP {} for {}",
response.status(),
file.filename
@@ -288,7 +288,7 @@ async fn download_file(
}
while let Some(chunk) = stream.next().await {
let chunk = chunk.map_err(|e| KonError::DownloadFailed(e.to_string()))?;
let chunk = chunk.map_err(|e| MagnotiaError::DownloadFailed(e.to_string()))?;
std::io::Write::write_all(&mut out, &chunk)?;
hasher.update(&chunk);
downloaded += chunk.len() as u64;
@@ -316,7 +316,7 @@ async fn download_file(
let actual = format!("{:x}", hasher.finalize());
if actual != file.sha256 {
let _ = std::fs::remove_file(&part_path);
return Err(KonError::DownloadFailed(format!(
return Err(MagnotiaError::DownloadFailed(format!(
"SHA256 mismatch for {}: expected {}, got {}",
file.filename, file.sha256, actual
)));
@@ -354,7 +354,7 @@ mod tests {
let list = list_downloaded();
// In test environment, no models are downloaded
// This just verifies the function doesn't panic
assert!(list.len() <= kon_core::model_registry::all_models().len());
assert!(list.len() <= magnotia_core::model_registry::all_models().len());
}
#[test]
@@ -478,7 +478,7 @@ mod tests {
let file = ModelFile {
filename: leak(dest.file_name().unwrap().to_string_lossy().into_owned()),
url: leak(format!("http://{addr}/fixture.bin")),
size: kon_core::types::Megabytes(0),
size: magnotia_core::types::Megabytes(0),
sha256: leak(expected_sha.clone()),
};
let id = ModelId::new("test-fixture");
@@ -513,7 +513,7 @@ mod tests {
let file = ModelFile {
filename: leak(dest.file_name().unwrap().to_string_lossy().into_owned()),
url: leak(format!("http://{addr}/fixture.bin")),
size: kon_core::types::Megabytes(0),
size: magnotia_core::types::Megabytes(0),
sha256: leak(expected_sha),
};
let id = ModelId::new("test-fixture");
@@ -568,7 +568,7 @@ mod tests {
let file = ModelFile {
filename: leak(dest.file_name().unwrap().to_string_lossy().into_owned()),
url: leak(format!("http://{addr}/fixture.bin")),
size: kon_core::types::Megabytes(0),
size: magnotia_core::types::Megabytes(0),
sha256: leak("0".repeat(64)),
};
let id = ModelId::new("test-fixture");
@@ -596,7 +596,7 @@ mod tests {
let file = ModelFile {
filename: leak(dest.file_name().unwrap().to_string_lossy().into_owned()),
url: leak(format!("http://{addr}/fixture.bin")),
size: kon_core::types::Megabytes(0),
size: magnotia_core::types::Megabytes(0),
sha256: leak("deadbeef".repeat(8)),
};
let id = ModelId::new("test-fixture");