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

@@ -3,10 +3,10 @@
//
// Refresh triggers:
// - module load (first time)
// - kon:task-completed (from page.svelte.ts completeTask)
// - kon:step-completed (from MicroSteps.svelte)
// - kon:task-uncompleted (new event, emitted by uncompleteTask in Task 10)
// - kon:task-deleted (new event, emitted by deleteTask in Task 10)
// - magnotia:task-completed (from page.svelte.ts completeTask)
// - magnotia:step-completed (from MicroSteps.svelte)
// - magnotia:task-uncompleted (new event, emitted by uncompleteTask in Task 10)
// - magnotia:task-deleted (new event, emitted by deleteTask in Task 10)
// - window focus (for day rollover while the app stayed open
// past midnight)
//
@@ -47,10 +47,10 @@ if (typeof window !== "undefined") {
const handler = () => {
refresh().catch(() => {});
};
window.addEventListener("kon:task-completed", handler);
window.addEventListener("kon:step-completed", handler);
window.addEventListener("kon:task-uncompleted", handler);
window.addEventListener("kon:task-deleted", handler);
window.addEventListener("magnotia:task-completed", handler);
window.addEventListener("magnotia:step-completed", handler);
window.addEventListener("magnotia:task-uncompleted", handler);
window.addEventListener("magnotia:task-deleted", handler);
window.addEventListener("focus", handler);
if (hasTauriRuntime()) {

View File

@@ -12,7 +12,7 @@
// so closing the window mid-timer still gets you the "done" signal
// on next launch.
const STORAGE_KEY = "kon.focusTimer.v1";
const STORAGE_KEY = "magnotia.focusTimer.v1";
const TICK_INTERVAL_MS = 250;
export type FocusTimerPersisted = {
@@ -114,7 +114,7 @@ function createFocusTimerStore() {
writePersisted(null);
stopTick();
if (wasActive && typeof window !== "undefined") {
window.dispatchEvent(new CustomEvent("kon:focus-timer-cancelled"));
window.dispatchEvent(new CustomEvent("magnotia:focus-timer-cancelled"));
}
}
@@ -172,7 +172,7 @@ function createFocusTimerStore() {
osc.onended = () => ctx.close().catch(() => {});
} catch { /* audio is a nicety; never fatal */ }
window.dispatchEvent(new CustomEvent("kon:focus-timer-complete", {
window.dispatchEvent(new CustomEvent("magnotia:focus-timer-complete", {
detail: { taskId, label },
}));
}

View File

@@ -13,7 +13,7 @@ import { page, settings, tasks } from "$lib/stores/page.svelte.js";
import { toasts } from "$lib/stores/toasts.svelte.js";
const TIME_RULE_POLL_MS = 30_000;
const RULES_CHANGED_EVENT = "kon:implementation-rules-changed";
const RULES_CHANGED_EVENT = "magnotia:implementation-rules-changed";
export const implementationRules = $state<ImplementationRule[]>([]);
@@ -157,7 +157,7 @@ async function executeAction(action: ImplementationRuleAction): Promise<void> {
return;
}
if (action.kind === "start_timer") {
window.dispatchEvent(new CustomEvent("kon:start-timer", {
window.dispatchEvent(new CustomEvent("magnotia:start-timer", {
detail: {
taskId: action.taskId ?? null,
seconds: 300,
@@ -239,8 +239,8 @@ export function startImplementationIntentions(): void {
void loadImplementationRules(true)
.then(() => checkTimeRules())
.catch(() => {});
window.addEventListener("kon:task-completed", onTaskCompleted);
window.addEventListener("kon:morning-triage-finished", onMorningTriageFinished);
window.addEventListener("magnotia:task-completed", onTaskCompleted);
window.addEventListener("magnotia:morning-triage-finished", onMorningTriageFinished);
window.addEventListener(RULES_CHANGED_EVENT, onRulesChanged);
timePollHandle = setInterval(() => {
void checkTimeRules().catch(() => {});
@@ -250,8 +250,8 @@ export function startImplementationIntentions(): void {
export function stopImplementationIntentions(): void {
if (!started) return;
started = false;
window.removeEventListener("kon:task-completed", onTaskCompleted);
window.removeEventListener("kon:morning-triage-finished", onMorningTriageFinished);
window.removeEventListener("magnotia:task-completed", onTaskCompleted);
window.removeEventListener("magnotia:morning-triage-finished", onMorningTriageFinished);
window.removeEventListener(RULES_CHANGED_EVENT, onRulesChanged);
if (timePollHandle !== null) {
clearInterval(timePollHandle);

View File

@@ -1,5 +1,5 @@
// Phase 6 Margot nudge bus. Frontend-owned, subscribes to in-app
// signals Corbie already produces, applies suppression, and fans out
// signals Magnotia already produces, applies suppression, and fans out
// to OS notification (via Rust's deliver_nudge) + optional TTS.
//
// Why frontend-only: OS-wide keyboard/window detection is fragile
@@ -191,7 +191,7 @@ async function checkPendingMorningTriage() {
triageNudgeFiredOnKey = today;
void deliver(
"A few things waiting",
"When you're ready, Corbie has your morning list. No rush.",
"When you're ready, Magnotia has your morning list. No rush.",
);
}
@@ -236,12 +236,12 @@ export function startNudgeBus(): void {
if (typeof window === "undefined") return;
started = true;
window.addEventListener("kon:start-timer", onTimerStart);
window.addEventListener("kon:focus-timer-complete", resetTimerState);
window.addEventListener("kon:focus-timer-cancelled", resetTimerState);
window.addEventListener("kon:microstep-generated", onMicroStepGenerated);
window.addEventListener("kon:step-completed", onStepOrTaskCompleted);
window.addEventListener("kon:task-completed", onStepOrTaskCompleted);
window.addEventListener("magnotia:start-timer", onTimerStart);
window.addEventListener("magnotia:focus-timer-complete", resetTimerState);
window.addEventListener("magnotia:focus-timer-cancelled", resetTimerState);
window.addEventListener("magnotia:microstep-generated", onMicroStepGenerated);
window.addEventListener("magnotia:step-completed", onStepOrTaskCompleted);
window.addEventListener("magnotia:task-completed", onStepOrTaskCompleted);
window.addEventListener("focus", onFocus);
window.addEventListener("blur", onBlur);
@@ -265,12 +265,12 @@ export function stopNudgeBus(): void {
if (!started) return;
started = false;
window.removeEventListener("kon:start-timer", onTimerStart);
window.removeEventListener("kon:focus-timer-complete", resetTimerState);
window.removeEventListener("kon:focus-timer-cancelled", resetTimerState);
window.removeEventListener("kon:microstep-generated", onMicroStepGenerated);
window.removeEventListener("kon:step-completed", onStepOrTaskCompleted);
window.removeEventListener("kon:task-completed", onStepOrTaskCompleted);
window.removeEventListener("magnotia:start-timer", onTimerStart);
window.removeEventListener("magnotia:focus-timer-complete", resetTimerState);
window.removeEventListener("magnotia:focus-timer-cancelled", resetTimerState);
window.removeEventListener("magnotia:microstep-generated", onMicroStepGenerated);
window.removeEventListener("magnotia:step-completed", onStepOrTaskCompleted);
window.removeEventListener("magnotia:task-completed", onStepOrTaskCompleted);
window.removeEventListener("focus", onFocus);
window.removeEventListener("blur", onBlur);

View File

@@ -36,10 +36,10 @@ export const page = $state<PageState>({
taskSidebarOpen: false,
});
const SETTINGS_KEY = "kon_settings";
const PROFILES_KEY = "kon_profiles";
const TASK_LISTS_KEY = "kon_task_lists";
const TEMPLATES_KEY = "kon_templates";
const SETTINGS_KEY = "magnotia_settings";
const PROFILES_KEY = "magnotia_profiles";
const TASK_LISTS_KEY = "magnotia_task_lists";
const TEMPLATES_KEY = "magnotia_templates";
const defaults: SettingsState = {
engine: "whisper",
@@ -102,8 +102,8 @@ function loadSettings(): SettingsState {
queueMicrotask(() => {
toasts.warn(
"Settings reset",
"Your saved settings couldn't be read, so Kon fell back to defaults. "
+ "Earlier Kon builds can still read your old data.",
"Your saved settings couldn't be read, so Magnotia fell back to defaults. "
+ "Earlier Magnotia builds can still read your old data.",
);
});
}
@@ -117,7 +117,7 @@ export const settings = $state<SettingsState>(loadSettings());
export function saveSettings() {
if (!canUseStorage()) return;
// Versioned envelope {version, data}. Older Kon builds that used
// Versioned envelope {version, data}. Older Magnotia builds that used
// the bare-object layout can still spread the `data` key over
// their defaults — they will just silently drop fields they don't
// know about, which is the same behaviour as today.
@@ -459,7 +459,7 @@ export async function deleteTask(id: string) {
tasks.splice(idx, 1);
broadcastTasks();
if (typeof window !== "undefined") {
window.dispatchEvent(new CustomEvent("kon:task-deleted", { detail: { id } }));
window.dispatchEvent(new CustomEvent("magnotia:task-deleted", { detail: { id } }));
}
}
} catch (err) {
@@ -477,7 +477,7 @@ export async function completeTask(id: string) {
// to this to clear micro-step-idle timers for the completed task
// and, later, to drive Phase 7 "after a task completes" rules.
if (typeof window !== "undefined") {
window.dispatchEvent(new CustomEvent("kon:task-completed", { detail: { id } }));
window.dispatchEvent(new CustomEvent("magnotia:task-completed", { detail: { id } }));
}
} catch (err) {
toasts.error("Couldn't complete task", errorMessage(err));
@@ -491,7 +491,7 @@ export async function uncompleteTask(id: string) {
await invoke("uncomplete_task_cmd", { id });
applyLocalTaskUpdate(id, { done: false, doneAt: null });
if (typeof window !== "undefined") {
window.dispatchEvent(new CustomEvent("kon:task-uncompleted", { detail: { id } }));
window.dispatchEvent(new CustomEvent("magnotia:task-uncompleted", { detail: { id } }));
}
} catch (err) {
toasts.error("Couldn't uncomplete task", errorMessage(err));
@@ -504,7 +504,7 @@ interface TaskChannelMessage {
}
const taskChannel = typeof BroadcastChannel !== "undefined"
? new BroadcastChannel("kon_task_sync")
? new BroadcastChannel("magnotia_task_sync")
: null;
if (taskChannel) {
@@ -654,7 +654,7 @@ interface TaskListChannelMessage {
}
const taskListChannel = typeof BroadcastChannel !== "undefined"
? new BroadcastChannel("kon_task_lists")
? new BroadcastChannel("magnotia_task_lists")
: null;
if (taskListChannel) {

View File

@@ -6,7 +6,7 @@ import type { AccessibilityPreferences, Preferences } from "$lib/types/app";
import { errorMessage } from "$lib/utils/errors.js";
import { toasts } from "./toasts.svelte.ts";
export const PREFERENCES_CHANGED_EVENT = "kon:preferences-changed";
export const PREFERENCES_CHANGED_EVENT = "magnotia:preferences-changed";
type FontFamilies = Record<AccessibilityPreferences["fontFamily"], string>;

View File

@@ -1,7 +1,7 @@
import type { ToastItem, ToastSeverity } from "$lib/types/app";
import { errorMessage } from "$lib/utils/errors.js";
// Minimal toast store. Roll-our-own (no svelte-french-toast etc) so Kon
// Minimal toast store. Roll-our-own (no svelte-french-toast etc) so Magnotia
// stays lean. Toasts auto-dismiss after `duration` ms unless duration is 0
// (sticky) or unless the user clicks the close button.
//