use super::*;
#[cfg(feature = "bundled-embedder")]
const DEFAULT_CONFIG_TOML: &str = "\
# Auto-generated by `mnem init`. Override with `mnem config set <key> <val>`
# or edit this file. See https://github.com/Uranid/mnem/blob/main/CONFIGURABLES.md
[embed]
provider = \"onnx\"
model = \"all-MiniLM-L6-v2\"
";
#[cfg(not(feature = "bundled-embedder"))]
const DEFAULT_CONFIG_TOML: &str = "\
# Auto-generated by `mnem init`. Override with `mnem config set <key> <val>`
# or edit this file. See https://github.com/Uranid/mnem/blob/main/CONFIGURABLES.md
[embed]
provider = \"ollama\"
model = \"nomic-embed-text\"
";
#[cfg(feature = "bundled-embedder")]
const DEFAULT_PROVIDER_DESC: &str = "onnx:all-MiniLM-L6-v2";
#[cfg(not(feature = "bundled-embedder"))]
const DEFAULT_PROVIDER_DESC: &str = "ollama:nomic-embed-text";
#[derive(clap::Args, Debug)]
#[command(after_long_help = "\
Examples:
mnem init # create .mnem/ in the current directory
mnem init ~/notes # create ~/notes/.mnem/
mnem -R ~/notes status # verify by reading op_id + head commit
")]
pub(crate) struct Args {
pub path: Option<std::path::PathBuf>,
}
pub(crate) fn run(_override: Option<&Path>, args: Args) -> Result<()> {
let target = args
.path
.unwrap_or_else(|| std::env::current_dir().unwrap_or_default());
let data_dir = target.join(repo::MNEM_DIR);
if data_dir.exists() {
bail!(
"already a mnem repository at {}\n\
hint: remove the existing `.mnem/` if you meant a fresh repo, or run \
`mnem status` to inspect it. See docs/RUNBOOK.md#6-mid-commit-crash-recovery \
for recovery semantics.",
data_dir.display()
);
}
let (bs, ohs) = repo::create_or_open_stores(&data_dir)?;
let r = ReadonlyRepo::init(bs, ohs)?;
let cfg_path = config::path_of(&data_dir);
if !cfg_path.exists() {
match std::fs::write(&cfg_path, DEFAULT_CONFIG_TOML) {
Ok(()) => {
println!(
" seeded config: {} ([embed] {})",
cfg_path.display(),
DEFAULT_PROVIDER_DESC
);
}
Err(e) => {
eprintln!(
"(warn: failed to seed {}: {e}; run `mnem config set embed.provider {}` manually)",
cfg_path.display(),
DEFAULT_PROVIDER_DESC.split(':').next().unwrap_or("ollama")
);
}
}
}
seed_anchor_node(&r, &data_dir);
println!("initialised mnem repo in {}", data_dir.display());
println!(" root op: {}", r.op_id());
crate::global::register_repo(&target);
Ok(())
}
pub(crate) fn init_mnem_dir(parent: &Path) -> Result<()> {
let data_dir = parent.join(repo::MNEM_DIR);
if data_dir.exists() {
return Ok(());
}
let (bs, ohs) = repo::create_or_open_stores(&data_dir)?;
let r = ReadonlyRepo::init(bs, ohs)?;
let cfg_path = config::path_of(&data_dir);
if !cfg_path.exists() {
let _ = std::fs::write(&cfg_path, DEFAULT_CONFIG_TOML);
}
seed_anchor_node(&r, &data_dir);
Ok(())
}
const ANCHOR_NODE_ID: &str = "00000000-0000-7000-8000-6d6e656d0001";
fn seed_anchor_node(repo: &ReadonlyRepo, _data_dir: &std::path::Path) {
let anchor_id = NodeId::parse_uuid(ANCHOR_NODE_ID)
.expect("ANCHOR_NODE_ID is a valid UUID; this is a compile-time constant");
let node = Node::new(anchor_id, "Meta");
let mut tx = repo.start_transaction();
match tx.add_node(&node) {
Ok(_) => {}
Err(_) => return,
};
let _ = tx.commit("mnem init", "seed anchor node");
}