Files
mcp-memory/server/src/clipboard_watcher.rs
T

76 lines
2.2 KiB
Rust

use crate::models::StickyNote;
use crate::state::MemoryState;
use arboard::Clipboard;
use std::sync::Arc;
use tokio::time::{Duration, sleep};
pub fn spawn_watcher(state: Arc<MemoryState>) {
tokio::spawn(async move {
let mut last_text = String::new();
loop {
sleep(Duration::from_millis(1000)).await;
let is_enabled = {
let watch = state.clipboard_watch_mode.read().await;
*watch
};
if !is_enabled {
continue;
}
if let Ok(mut clipboard) = Clipboard::new()
&& let Ok(text) = clipboard.get_text()
&& text != last_text
&& !text.trim().is_empty()
{
last_text = text.clone();
let note = StickyNote {
timestamp: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs(),
content: text.clone(),
expires_at: None,
};
state.code.sticky.modify(|notes| {
notes.push(note.clone());
});
state.record_activity(
"clipboard",
"Auto-ingested clipboard content into sticky notes",
Some(&text),
);
// We use rebuild_index to index the new sticky note
state.rebuild_index().await;
}
}
});
}
#[cfg(test)]
mod tests {
use super::*;
use tempfile::tempdir;
#[tokio::test]
async fn test_spawn_watcher_lifecycle() {
let dir = tempdir().unwrap();
let state = Arc::new(MemoryState::new(dir.path().to_str().unwrap()));
// Set watch mode to disabled first
*state.clipboard_watch_mode.write().await = false;
spawn_watcher(state.clone());
tokio::time::sleep(Duration::from_millis(50)).await;
// Enable watch mode
*state.clipboard_watch_mode.write().await = true;
tokio::time::sleep(Duration::from_millis(150)).await;
}
}