diff --git a/poc-memory/src/cli/node.rs b/poc-memory/src/cli/node.rs index 7d2e536..ea261fb 100644 --- a/poc-memory/src/cli/node.rs +++ b/poc-memory/src/cli/node.rs @@ -246,6 +246,48 @@ pub fn cmd_render(key: &[String]) -> Result<(), String> { Ok(()) } +/// Check content for common inline reference problems: +/// - `poc-memory render key` embedded in content (render artifact, should be just `key`) +/// - `→ something` where something doesn't parse as a valid key +/// - `key` referencing a node that doesn't exist +fn validate_inline_refs(content: &str, store: &store::Store) -> Vec { + let mut warnings = Vec::new(); + + for line in content.lines() { + // Check for render commands embedded in content + if line.contains("poc-memory render ") && !line.starts_with(" ") { + // Skip lines that look like CLI documentation/examples + if !line.contains("CLI") && !line.contains("equivalent") && !line.contains("tool") { + warnings.push(format!( + "render command in content (should be just `key`): {}", + line.chars().take(80).collect::(), + )); + } + } + + // Check → references + if let Some(rest) = line.trim().strip_prefix("→ ") { + // Extract the key (may be backtick-quoted) + let key = rest.trim().trim_matches('`').trim(); + if !key.is_empty() && !store.nodes.contains_key(key) { + // Might be a poc-memory render artifact + if let Some(k) = key.strip_prefix("poc-memory render ") { + warnings.push(format!( + "render artifact in → reference (use `{}` not `poc-memory render {}`)", k, k, + )); + } else if key.contains(' ') { + warnings.push(format!( + "→ reference doesn't look like a key: → {}", key, + )); + } + // Don't warn about missing keys — the target might be created later + } + } + } + + warnings +} + pub fn cmd_history(key: &[String], full: bool) -> Result<(), String> { if key.is_empty() { return Err("history requires a key".into()); @@ -332,6 +374,14 @@ pub fn cmd_write(key: &[String]) -> Result<(), String> { let mut store = store::Store::load()?; let key = store.resolve_key(&raw_key).unwrap_or(raw_key); + + // Validate inline references: warn about render commands embedded + // in content (should be just `key`) and broken references. + let warnings = validate_inline_refs(&content, &store); + for w in &warnings { + eprintln!("warning: {}", w); + } + let result = store.upsert(&key, &content)?; match result { "unchanged" => println!("No change: '{}'", key),