Skip to main content

agentmux_srv/migrations/
m0001_legacy_data_dir.rs

1// Copyright 2026, AgentMux Corp.
2// SPDX-License-Identifier: Apache-2.0
3
4use super::{Migration, MigrationContext, MigrationError, MigrationScope};
5use std::path::Path;
6
7pub struct M0001LegacyDataDir;
8
9impl Migration for M0001LegacyDataDir {
10    fn id(&self) -> &'static str { "0001_legacy_data_dir" }
11    fn scope(&self) -> MigrationScope { MigrationScope::Global }
12    fn description(&self) -> &'static str { "Move ~/.waveterm data directory to ~/.agentmux" }
13
14    fn up(&self, ctx: &MigrationContext) -> Result<(), MigrationError> {
15        // Runner always creates data_dir/db/ before migrations run, so
16        // data_dir.exists() is always true and cannot guard against overwriting
17        // a real agentmux install. Use agents/ instead — runner never creates it.
18        if ctx.home.join("agents").exists() {
19            return Ok(());
20        }
21        let home_dir = dirs::home_dir()
22            .ok_or_else(|| MigrationError("cannot resolve OS home dir".to_owned()))?;
23        let old_dir = home_dir.join(".waveterm");
24        if !old_dir.exists() {
25            return Ok(());
26        }
27        copy_dir_all(&old_dir, &ctx.data_dir)
28            .map_err(|e| MigrationError(format!("legacy data dir copy: {}", e)))
29    }
30}
31
32fn copy_dir_all(src: &Path, dst: &Path) -> Result<(), String> {
33    std::fs::create_dir_all(dst)
34        .map_err(|e| format!("cannot create {}: {}", dst.display(), e))?;
35    for entry in std::fs::read_dir(src)
36        .map_err(|e| format!("cannot read {}: {}", src.display(), e))?
37    {
38        let entry = entry.map_err(|e| format!("read_dir entry: {}", e))?;
39        let src_path = entry.path();
40        let dst_path = dst.join(entry.file_name());
41        if src_path.is_dir() {
42            copy_dir_all(&src_path, &dst_path)?;
43        } else {
44            std::fs::copy(&src_path, &dst_path)
45                .map_err(|e| format!("copy {}: {}", src_path.display(), e))?;
46        }
47    }
48    Ok(())
49}