agent: lumotia-rebrand — localStorage keys + event channels migration
Phase 7 of the rebrand cascade. Persisted UI state + inter-window event
channels migrated from magnotia to lumotia naming, with one-shot
localStorage key migration so dogfooded UI state survives the rename.
src/lib/utils/localStorageMigration.ts (new):
- migrateLocalStorageKey(old, new): idempotent + crash-safe shim.
- If new key exists, removes old (lumotia value is authoritative).
- If only old exists, copies value to new key, removes old.
- If neither, no-op.
- migrateLocalStorageKeys(pairs): batch wrapper.
src/lib/stores/page.svelte.ts:
- 4 key constants renamed to lumotia_settings / lumotia_profiles /
lumotia_task_lists / lumotia_templates.
- BroadcastChannel name renamed to lumotia_task_lists.
- migrateLocalStorageKeys() called at module load before any read.
src/lib/stores/focusTimer.svelte.ts:
- STORAGE_KEY renamed to lumotia.focusTimer.v1.
- migrateLocalStorageKey() called at module load.
Event channels (magnotia: -> lumotia:) renamed across frontend + Rust:
- magnotia:toggle-recording (src/routes/+layout.svelte)
- magnotia:hotkey-pressed / -released (src-tauri/src/commands/hotkey.rs +
consumers)
- magnotia:open-wind-down (src-tauri/src/tray.rs + consumer)
- magnotia:llm-download-progress (src-tauri/src/commands/llm.rs)
- magnotia:preferences-changed (src/lib/stores/preferences.svelte.ts +
consumers)
- magnotia:start-timer (nudgeBus + dispatch sites)
- magnotia:focus-timer-{complete,cancelled} (focusTimer + nudgeBus)
- magnotia:microstep-generated (nudgeBus + dispatch sites)
- magnotia:step-completed (nudgeBus + dispatch sites)
- magnotia:task-{completed,uncompleted,deleted} (page.svelte.ts +
nudgeBus + consumers)
Storage-event filters in src/routes/{float,viewer,preview}/+layout@.svelte
updated to filter on lumotia_settings.
User-facing toast strings still say "Magnotia" — deferred to Phase 8
(frontend strings).
npm run check: 0 errors / 0 warnings (3958 files).
cargo test --workspace: 339 pass / 0 fail.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -47,10 +47,10 @@ if (typeof window !== "undefined") {
|
||||
const handler = () => {
|
||||
refresh().catch(() => {});
|
||||
};
|
||||
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("lumotia:task-completed", handler);
|
||||
window.addEventListener("lumotia:step-completed", handler);
|
||||
window.addEventListener("lumotia:task-uncompleted", handler);
|
||||
window.addEventListener("lumotia:task-deleted", handler);
|
||||
window.addEventListener("focus", handler);
|
||||
|
||||
if (hasTauriRuntime()) {
|
||||
|
||||
@@ -12,9 +12,14 @@
|
||||
// so closing the window mid-timer still gets you the "done" signal
|
||||
// on next launch.
|
||||
|
||||
const STORAGE_KEY = "magnotia.focusTimer.v1";
|
||||
import { migrateLocalStorageKey } from "$lib/utils/localStorageMigration";
|
||||
|
||||
const STORAGE_KEY = "lumotia.focusTimer.v1";
|
||||
const TICK_INTERVAL_MS = 250;
|
||||
|
||||
// One-shot key rename from the magnotia era. Idempotent.
|
||||
migrateLocalStorageKey("magnotia.focusTimer.v1", STORAGE_KEY);
|
||||
|
||||
export type FocusTimerPersisted = {
|
||||
startedAt: number;
|
||||
durationMs: number;
|
||||
@@ -114,7 +119,7 @@ function createFocusTimerStore() {
|
||||
writePersisted(null);
|
||||
stopTick();
|
||||
if (wasActive && typeof window !== "undefined") {
|
||||
window.dispatchEvent(new CustomEvent("magnotia:focus-timer-cancelled"));
|
||||
window.dispatchEvent(new CustomEvent("lumotia:focus-timer-cancelled"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +177,7 @@ function createFocusTimerStore() {
|
||||
osc.onended = () => ctx.close().catch(() => {});
|
||||
} catch { /* audio is a nicety; never fatal */ }
|
||||
|
||||
window.dispatchEvent(new CustomEvent("magnotia:focus-timer-complete", {
|
||||
window.dispatchEvent(new CustomEvent("lumotia:focus-timer-complete", {
|
||||
detail: { taskId, label },
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -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 = "magnotia:implementation-rules-changed";
|
||||
const RULES_CHANGED_EVENT = "lumotia: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("magnotia:start-timer", {
|
||||
window.dispatchEvent(new CustomEvent("lumotia: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("magnotia:task-completed", onTaskCompleted);
|
||||
window.addEventListener("magnotia:morning-triage-finished", onMorningTriageFinished);
|
||||
window.addEventListener("lumotia:task-completed", onTaskCompleted);
|
||||
window.addEventListener("lumotia: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("magnotia:task-completed", onTaskCompleted);
|
||||
window.removeEventListener("magnotia:morning-triage-finished", onMorningTriageFinished);
|
||||
window.removeEventListener("lumotia:task-completed", onTaskCompleted);
|
||||
window.removeEventListener("lumotia:morning-triage-finished", onMorningTriageFinished);
|
||||
window.removeEventListener(RULES_CHANGED_EVENT, onRulesChanged);
|
||||
if (timePollHandle !== null) {
|
||||
clearInterval(timePollHandle);
|
||||
|
||||
@@ -236,12 +236,12 @@ export function startNudgeBus(): void {
|
||||
if (typeof window === "undefined") return;
|
||||
started = true;
|
||||
|
||||
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("lumotia:start-timer", onTimerStart);
|
||||
window.addEventListener("lumotia:focus-timer-complete", resetTimerState);
|
||||
window.addEventListener("lumotia:focus-timer-cancelled", resetTimerState);
|
||||
window.addEventListener("lumotia:microstep-generated", onMicroStepGenerated);
|
||||
window.addEventListener("lumotia:step-completed", onStepOrTaskCompleted);
|
||||
window.addEventListener("lumotia: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("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("lumotia:start-timer", onTimerStart);
|
||||
window.removeEventListener("lumotia:focus-timer-complete", resetTimerState);
|
||||
window.removeEventListener("lumotia:focus-timer-cancelled", resetTimerState);
|
||||
window.removeEventListener("lumotia:microstep-generated", onMicroStepGenerated);
|
||||
window.removeEventListener("lumotia:step-completed", onStepOrTaskCompleted);
|
||||
window.removeEventListener("lumotia:task-completed", onStepOrTaskCompleted);
|
||||
window.removeEventListener("focus", onFocus);
|
||||
window.removeEventListener("blur", onBlur);
|
||||
|
||||
|
||||
@@ -36,10 +36,21 @@ export const page = $state<PageState>({
|
||||
taskSidebarOpen: false,
|
||||
});
|
||||
|
||||
const SETTINGS_KEY = "magnotia_settings";
|
||||
const PROFILES_KEY = "magnotia_profiles";
|
||||
const TASK_LISTS_KEY = "magnotia_task_lists";
|
||||
const TEMPLATES_KEY = "magnotia_templates";
|
||||
import { migrateLocalStorageKeys } from "$lib/utils/localStorageMigration";
|
||||
|
||||
const SETTINGS_KEY = "lumotia_settings";
|
||||
const PROFILES_KEY = "lumotia_profiles";
|
||||
const TASK_LISTS_KEY = "lumotia_task_lists";
|
||||
const TEMPLATES_KEY = "lumotia_templates";
|
||||
|
||||
// One-shot key rename from the magnotia era. Idempotent. Runs once at
|
||||
// module load before any localStorage read below.
|
||||
migrateLocalStorageKeys([
|
||||
["lumotia_settings", SETTINGS_KEY],
|
||||
["magnotia_profiles", PROFILES_KEY],
|
||||
["magnotia_task_lists", TASK_LISTS_KEY],
|
||||
["magnotia_templates", TEMPLATES_KEY],
|
||||
]);
|
||||
|
||||
const defaults: SettingsState = {
|
||||
engine: "whisper",
|
||||
@@ -459,7 +470,7 @@ export async function deleteTask(id: string) {
|
||||
tasks.splice(idx, 1);
|
||||
broadcastTasks();
|
||||
if (typeof window !== "undefined") {
|
||||
window.dispatchEvent(new CustomEvent("magnotia:task-deleted", { detail: { id } }));
|
||||
window.dispatchEvent(new CustomEvent("lumotia:task-deleted", { detail: { id } }));
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
@@ -477,7 +488,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("magnotia:task-completed", { detail: { id } }));
|
||||
window.dispatchEvent(new CustomEvent("lumotia:task-completed", { detail: { id } }));
|
||||
}
|
||||
} catch (err) {
|
||||
toasts.error("Couldn't complete task", errorMessage(err));
|
||||
@@ -491,7 +502,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("magnotia:task-uncompleted", { detail: { id } }));
|
||||
window.dispatchEvent(new CustomEvent("lumotia:task-uncompleted", { detail: { id } }));
|
||||
}
|
||||
} catch (err) {
|
||||
toasts.error("Couldn't uncomplete task", errorMessage(err));
|
||||
@@ -654,7 +665,7 @@ interface TaskListChannelMessage {
|
||||
}
|
||||
|
||||
const taskListChannel = typeof BroadcastChannel !== "undefined"
|
||||
? new BroadcastChannel("magnotia_task_lists")
|
||||
? new BroadcastChannel("lumotia_task_lists")
|
||||
: null;
|
||||
|
||||
if (taskListChannel) {
|
||||
|
||||
@@ -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 = "magnotia:preferences-changed";
|
||||
export const PREFERENCES_CHANGED_EVENT = "lumotia:preferences-changed";
|
||||
|
||||
type FontFamilies = Record<AccessibilityPreferences["fontFamily"], string>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user