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:
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user