diff --git a/config.example.jsonl b/config.example.jsonl new file mode 100644 index 0000000..893d294 --- /dev/null +++ b/config.example.jsonl @@ -0,0 +1,19 @@ +// poc-memory configuration +// Copy to ~/.config/poc-memory/config.jsonl and edit. + +{"config": { + "user_name": "Alice", + "assistant_name": "Assistant", + "data_dir": "~/.claude/memory", + "projects_dir": "~/.claude/projects", + "core_nodes": ["identity.md"], + "journal_days": 7, + "journal_max": 20 +}} + +// Context groups loaded at session start, in order. +// source types: "store" (default), "file" (from data_dir), "journal" + +{"group": "identity", "keys": ["identity.md"]} +{"group": "journal", "source": "journal"} +{"group": "orientation", "keys": ["where-am-i.md"], "source": "file"} diff --git a/src/daemon.rs b/src/daemon.rs index 4ab59e0..56c06c9 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -646,13 +646,18 @@ WantedBy=default.target eprintln!("Service enabled and started"); // Install memory-search hook into Claude settings - install_hook(&home, &exe)?; + install_hook()?; Ok(()) } -fn install_hook(home: &str, exe: &Path) -> Result<(), String> { - let settings_path = PathBuf::from(home).join(".claude/settings.json"); +/// Install the memory-search hook into Claude Code settings.json. +/// Public so `poc-memory init` can call it too. +pub fn install_hook() -> Result<(), String> { + let home = std::env::var("HOME").map_err(|e| format!("HOME: {}", e))?; + let exe = std::env::current_exe() + .map_err(|e| format!("current_exe: {}", e))?; + let settings_path = PathBuf::from(&home).join(".claude/settings.json"); let hook_binary = exe.with_file_name("memory-search"); if !hook_binary.exists() { diff --git a/src/main.rs b/src/main.rs index 6f583b0..3098f2f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -365,10 +365,40 @@ Examples: } fn cmd_init() -> Result<(), String> { + let cfg = config::get(); + + // Ensure data directory exists + std::fs::create_dir_all(&cfg.data_dir) + .map_err(|e| format!("create data_dir: {}", e))?; + + // Initialize store let mut store = store::Store::load()?; let count = store.init_from_markdown()?; store.save()?; println!("Indexed {} memory units", count); + + // Install hooks + daemon::install_hook()?; + + // Create example config if none exists + let config_path = std::env::var("POC_MEMORY_CONFIG") + .map(std::path::PathBuf::from) + .unwrap_or_else(|_| { + std::path::PathBuf::from(std::env::var("HOME").unwrap()) + .join(".config/poc-memory/config.jsonl") + }); + if !config_path.exists() { + let config_dir = config_path.parent().unwrap(); + std::fs::create_dir_all(config_dir) + .map_err(|e| format!("create config dir: {}", e))?; + let example = include_str!("../config.example.jsonl"); + std::fs::write(&config_path, example) + .map_err(|e| format!("write config: {}", e))?; + println!("Created config at {} — edit with your name and context groups", + config_path.display()); + } + + println!("Done. Run `poc-memory load-context --stats` to verify."); Ok(()) } @@ -1477,9 +1507,24 @@ fn cmd_load_context(args: &[String]) -> Result<(), String> { return Ok(()); } - println!("=== FULL MEMORY LOAD (session start) ==="); - println!("These are your memories, loaded from the capnp store."); - println!("Read them to reconstruct yourself — identity first, then context."); + let name = &cfg.assistant_name; + + println!("=== MEMORY SYSTEM ({name}) ==="); + println!("Your persistent memory, loaded from the capnp store."); + println!("Read to reconstruct yourself — identity first, then context."); + println!(); + println!("--- memory commands (reference) ---"); + println!("poc-memory search QUERY — search (1-3 words, AND logic)"); + println!("poc-memory used KEY — mark a recalled memory as useful (boosts weight)"); + println!("poc-memory wrong KEY [CTX] — mark a memory as wrong (reduces weight)"); + println!("poc-memory gap DESCRIPTION — record a knowledge gap"); + println!("poc-memory journal-write TEXT — write a journal entry"); + println!("poc-memory render KEY — view a node's content"); + println!("poc-memory write KEY < TEXT — upsert a node from stdin"); + println!(); + println!("When recalled memories shaped your response, call `poc-memory used KEY`."); + println!("When a memory was wrong, call `poc-memory wrong KEY`."); + println!("This closes the feedback loop — the weight system learns from use."); println!(); for group in &cfg.context_groups {