agent: lumotia-rebrand — data dir migration shim + paths.rs rename
Phase 5 of the rebrand cascade per locked decision D1 (migrate in place).
crates/core/src/paths.rs:
- Hardcoded subdir strings renamed: magnotia/Magnotia -> lumotia/Lumotia
across all four OS branches (Linux XDG + dot-legacy, macOS Application
Support, Windows LOCALAPPDATA, fallback dot-dir).
- Database filename: magnotia.db -> lumotia.db.
- Test path fixtures renamed: /tmp/magnotia-test -> /tmp/lumotia-test.
- New MigrationStatus enum (Migrated / TargetAlreadyExists / NoLegacyFound).
- New migrate_legacy_data_dir() that probes the platform-correct legacy
magnotia path, renames it to the lumotia equivalent via fs::rename, and
also renames magnotia.db -> lumotia.db inside if found. Idempotent: safe
to call on every boot. Refuses to overwrite an existing lumotia dir to
protect user data.
- Four new unit tests covering all branches via the test-friendly
migrate_legacy_data_dir_inner that takes an explicit legacy path.
crates/storage/src/database.rs:
- New migrate_legacy_setting_keys(pool) that renames any settings rows
with key matching magnotia_* to lumotia_*. Single SQL UPDATE with
NOT EXISTS guard so it leaves rows alone if a lumotia_ row already
exists. Re-exported from lib.rs.
src-tauri/src/lib.rs:
- Calls migrate_legacy_data_dir(&app_data_dir()) at the start of setup()
BEFORE database_path() resolves the now-renamed dir. Logs migration
outcome to lumotia_startup tracing target.
- Calls migrate_legacy_setting_keys(&db) immediately after init_db
returns. Logs only when rows are actually renamed.
src-tauri/src/{lib,commands/{diagnostics,rituals,transcripts}}.rs +
crates/storage/src/database.rs:
- All in-code references to magnotia_preferences, magnotia_history (in
comments), and magnotia_morning_triage_last_shown renamed to lumotia_*.
cargo build --workspace passes. cargo test --workspace: 334 pass, 0 fail
(up from 330; +4 paths::tests).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -335,7 +335,7 @@ async fn generate_diagnostic_report_inner(
|
||||
|
||||
if opts.include_settings {
|
||||
out.push_str("## Settings (sanitised)\n\n");
|
||||
match lumotia_storage::get_setting(&state.db, "magnotia_preferences").await {
|
||||
match lumotia_storage::get_setting(&state.db, "lumotia_preferences").await {
|
||||
Ok(Some(json)) => {
|
||||
out.push_str("```json\n");
|
||||
out.push_str(&sanitise_preferences_json(&json));
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
//!
|
||||
//! Stored under the existing SQLite settings table via
|
||||
//! `lumotia_storage::{get_setting, set_setting}` — same bag as
|
||||
//! `magnotia_preferences`.
|
||||
//! `lumotia_preferences`.
|
||||
|
||||
use lumotia_storage::{get_setting, set_setting};
|
||||
|
||||
use crate::AppState;
|
||||
|
||||
const LAST_TRIAGE_KEY: &str = "magnotia_morning_triage_last_shown";
|
||||
const LAST_TRIAGE_KEY: &str = "lumotia_morning_triage_last_shown";
|
||||
|
||||
/// Returns the YYYY-MM-DD date string stored on the last successful
|
||||
/// morning triage dismissal, or `None` if the user has never been
|
||||
|
||||
@@ -28,7 +28,7 @@ use crate::AppState;
|
||||
///
|
||||
/// Task 2.5 — `starred`, `manualTags`, `template`, `language`, `segmentsJson`
|
||||
/// were added to back the viewer metadata that previously lived only in the
|
||||
/// removed `magnotia_history` localStorage cache.
|
||||
/// removed `lumotia_history` localStorage cache.
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct TranscriptDto {
|
||||
|
||||
@@ -12,9 +12,13 @@ use sqlx::SqlitePool;
|
||||
use tauri::Manager;
|
||||
use tracing_subscriber::EnvFilter;
|
||||
|
||||
use lumotia_core::paths::{migrate_legacy_data_dir, MigrationStatus};
|
||||
use lumotia_core::types::EngineName;
|
||||
use lumotia_llm::LlmEngine;
|
||||
use lumotia_storage::{database_path, get_setting, init as init_db, prune_error_log, set_setting};
|
||||
use lumotia_storage::{
|
||||
app_data_dir, database_path, get_setting, init as init_db, migrate_legacy_setting_keys,
|
||||
prune_error_log, set_setting,
|
||||
};
|
||||
|
||||
/// How long to retain `error_log` rows. Pruned once on startup.
|
||||
/// 90 days is long enough to triage "this happened a few weeks ago"
|
||||
@@ -97,7 +101,7 @@ async fn save_preferences(
|
||||
state: tauri::State<'_, AppState>,
|
||||
preferences: String,
|
||||
) -> Result<(), String> {
|
||||
set_setting(&state.db, "magnotia_preferences", &preferences)
|
||||
set_setting(&state.db, "lumotia_preferences", &preferences)
|
||||
.await
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
@@ -220,6 +224,29 @@ pub fn run() {
|
||||
|
||||
builder
|
||||
.setup(|app| {
|
||||
// One-shot legacy data-dir migration: rename ~/.local/share/magnotia
|
||||
// (and macOS/Windows equivalents) to the lumotia path on first
|
||||
// launch after the rebrand. Safe to call every boot — idempotent.
|
||||
let t_migrate = Instant::now();
|
||||
let new_data_dir = app_data_dir();
|
||||
match migrate_legacy_data_dir(&new_data_dir) {
|
||||
Ok(MigrationStatus::Migrated { from, to, renamed_db }) => tracing::info!(
|
||||
target: "lumotia_startup",
|
||||
elapsed_ms = t_migrate.elapsed().as_millis(),
|
||||
from = %from.display(),
|
||||
to = %to.display(),
|
||||
renamed_db,
|
||||
"migrated legacy magnotia data dir to lumotia"
|
||||
),
|
||||
Ok(MigrationStatus::TargetAlreadyExists { .. }) => {}
|
||||
Ok(MigrationStatus::NoLegacyFound) => {}
|
||||
Err(e) => tracing::warn!(
|
||||
target: "lumotia_startup",
|
||||
error = %e,
|
||||
"legacy data dir migration failed — continuing with new path"
|
||||
),
|
||||
}
|
||||
|
||||
// Initialise database and startup settings in one runtime entry.
|
||||
let db_path = database_path();
|
||||
let (db, init_script) = tauri::async_runtime::block_on(async {
|
||||
@@ -229,6 +256,25 @@ pub fn run() {
|
||||
.map_err(|e| Box::new(e) as Box<dyn std::error::Error>)?;
|
||||
tracing::info!(target: "lumotia_startup", elapsed_ms = t0.elapsed().as_millis(), "DB init complete");
|
||||
|
||||
// One-shot settings-key migration: rename any leftover
|
||||
// `magnotia_*` rows from the magnotia era to `lumotia_*`.
|
||||
// Idempotent; logs only when rows are actually renamed.
|
||||
let t_keys = Instant::now();
|
||||
match migrate_legacy_setting_keys(&db).await {
|
||||
Ok(0) => {}
|
||||
Ok(n) => tracing::info!(
|
||||
target: "lumotia_startup",
|
||||
rows_renamed = n,
|
||||
elapsed_ms = t_keys.elapsed().as_millis(),
|
||||
"renamed legacy magnotia_* settings keys to lumotia_*"
|
||||
),
|
||||
Err(e) => tracing::warn!(
|
||||
target: "lumotia_startup",
|
||||
error = %e,
|
||||
"settings-key migration failed — continuing"
|
||||
),
|
||||
}
|
||||
|
||||
// Prune old `error_log` rows so the table doesn't grow unbounded
|
||||
// across months of dogfooding. Best-effort — a prune failure is
|
||||
// not worth blocking startup over.
|
||||
@@ -247,7 +293,7 @@ pub fn run() {
|
||||
|
||||
// Load saved preferences for webview injection.
|
||||
let t1 = Instant::now();
|
||||
let prefs_json = get_setting(&db, "magnotia_preferences").await.unwrap_or(None);
|
||||
let prefs_json = get_setting(&db, "lumotia_preferences").await.unwrap_or(None);
|
||||
tracing::info!(target: "lumotia_startup", elapsed_ms = t1.elapsed().as_millis(), "preferences load complete");
|
||||
let init_script = build_preferences_script(prefs_json);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user