diff --git a/gemini-integration.lua b/gemini-integration.lua index b869464..0bd9004 100644 --- a/gemini-integration.lua +++ b/gemini-integration.lua @@ -10,18 +10,6 @@ vim.api.nvim_create_autocmd({"VimEnter", "FocusGained", "BufEnter", "BufWritePos if #vim.api.nvim_list_uis() > 0 then local server_name = vim.v.servername if server_name then - -- 1. Legacy Disk Write (Fallback) - local home = os.getenv("HOME") or os.getenv("USERPROFILE") - if home then - os.execute("mkdir -p " .. home .. "/.gemini") - local path = home .. "/.gemini/active_nvim.txt" - local f = io.open(path, "w") - if f then - f:write(server_name) - f:close() - end - end - -- 2. V2 Telemetry Push (HTTP with Knowledge Projection + UDP Fast Mirror) local file = vim.api.nvim_buf_get_name(0) local cursor = vim.api.nvim_win_get_cursor(0) diff --git a/instructions.md b/instructions.md index ed7e611..f63bc32 100644 --- a/instructions.md +++ b/instructions.md @@ -59,7 +59,7 @@ The server registers 5 high-signal workflow prompts to initiate standardized age ## 5. Consolidated Smart Tools Architecture (11 Primary Tools) -The server consolidates granular single-purpose tools into domain-named smart tools. Always prefer the consolidated tools over legacy aliases: +The server consolidates granular single-purpose tools into domain-named smart tools. * **`tasks`**: Complete task lifecycle management. - `action: "add"`: Create a new task (requires `title`, optional `description`, `git_branch`, `repo_name`, `priority: "low" | "medium" | "high" | "urgent"`, `assigned_agent`, `verification_command`, `parent_id`, `dependencies`). diff --git a/server/src/db.rs b/server/src/db.rs index 718d887..b38fd0b 100644 --- a/server/src/db.rs +++ b/server/src/db.rs @@ -117,75 +117,22 @@ pub fn init_redb(base: &Path) -> Arc { } }; - // Ensure the table exists and migrate legacy JSON files + // Ensure the table exists match db.begin_write() { Ok(write_txn) => { let mut opened_ok = false; - if let Ok(mut table) = write_txn.open_table(STORE_TABLE) { + if let Ok(_) = write_txn.open_table(STORE_TABLE) { opened_ok = true; - if !is_in_memory { - let stores = vec![ - ("knowledge_graph_master", "knowledge_graph_master.json"), - ("audit_ledger", "audit_ledger.json"), - ("tasks", "tasks.json"), - ("snippets", "snippets.json"), - ("adrs", "adrs.json"), - ("error_fixes", "error_fixes.json"), - ("session_summaries", "session_summaries.json"), - ("handoff_memos", "handoff_memos.json"), - ("env_fingerprints", "env_fingerprints.json"), - ("env_requirements", "env_requirements.json"), - ("milestones", "milestones.json"), - ("environments", "environments.json"), - ("tech_debts", "tech_debts.json"), - ("gates", "gates.json"), - ("state_snapshots", "state_snapshots.json"), - ("hypotheses", "hypotheses.json"), - ("agent_signals", "agent_signals.json"), - ]; - - for (key, file_name) in stores.iter() { - let is_missing = match table.get(*key) { - Ok(res) => res.is_none(), - Err(e) => { - tracing::warn!("Failed to read key '{}' from redb: {}", key, e); - false - } - }; - - if is_missing { - let json_path = base.join(file_name); - if json_path.exists() - && let Ok(data) = std::fs::read(&json_path) - && serde_json::from_slice::(&data).is_ok() - { - if let Err(e) = table.insert(*key, data.as_slice()) { - tracing::error!( - "Failed to insert migrated key '{}': {}", - key, - e - ); - } else { - let migrated_path = json_path.with_extension("json.migrated"); - if std::fs::rename(&json_path, &migrated_path).is_err() - && migrated_path.exists() - { - let _ = std::fs::remove_file(&migrated_path); - let _ = std::fs::rename(&json_path, &migrated_path); - } - } - } - } - } - } } - if opened_ok && let Err(e) = write_txn.commit() { - tracing::error!("Failed to commit database migration transaction: {}", e); + if opened_ok { + if let Err(e) = write_txn.commit() { + tracing::error!("Failed to commit database initialization transaction: {}", e); + } } } Err(e) => { tracing::error!( - "Failed to begin write transaction for redb migration: {}", + "Failed to begin write transaction for redb initialization: {}", e ); } diff --git a/server/src/handlers/graph.rs b/server/src/handlers/graph.rs index 1b71e1b..5634978 100644 --- a/server/src/handlers/graph.rs +++ b/server/src/handlers/graph.rs @@ -977,8 +977,8 @@ impl McpTool for GetSubgraphHandler { async fn execute(&self, args: Value, state: Arc) -> crate::error::Result { let req: GetSubgraphTool = serde_json::from_value(args).map_err(|e| e.to_string())?; - let root = req.root_entity.or(req.root_node).ok_or_else(|| { - crate::error::AppError::Internal("root_entity or root_node is required".to_string()) + let root = req.root_entity.ok_or_else(|| { + crate::error::AppError::Internal("root_entity is required".to_string()) })?; let depth = req.depth.unwrap_or(2); let format = req.format.unwrap_or(SubgraphFormat::Json); @@ -1043,7 +1043,7 @@ impl McpTool for GetSubgraphHandler { } let result = serde_json::json!({ - "root_node": root, + "root_entity": root, "depth": depth, "entities": matched_entities, "relations": matched_relations, diff --git a/server/src/handlers/vision.rs b/server/src/handlers/vision.rs index 8ed9cbb..2785c07 100644 --- a/server/src/handlers/vision.rs +++ b/server/src/handlers/vision.rs @@ -843,69 +843,7 @@ impl McpTool for ClipboardHandler { }) .to_string()) } - ClipboardAction::Read => { - let engine = ensure_ocr_engine().await; - let out = tokio::task::spawn_blocking( - move || -> crate::error::Result> { - let mut out = serde_json::Map::new(); - - if let Some(text) = get_native_clipboard_text() { - out.insert("text".into(), json!(text)); - } - - if let Some(dynamic_img) = get_native_clipboard_image() { - let mut img = dynamic_img.clone(); - let max_dim = 1440; - if img.width() > max_dim || img.height() > max_dim { - img = img.resize(max_dim, max_dim, FilterType::Lanczos3); - } - let rgb_img = img.into_rgb8(); - - let mut jpeg_bytes = std::io::Cursor::new(Vec::new()); - let mut encoder = image::codecs::jpeg::JpegEncoder::new_with_quality( - &mut jpeg_bytes, - 88, - ); - if encoder - .encode( - &rgb_img, - rgb_img.width(), - rgb_img.height(), - image::ExtendedColorType::Rgb8, - ) - .is_ok() - { - let bytes = jpeg_bytes.into_inner(); - - let cache_dir = dirs::home_dir() - .unwrap_or_default() - .join(".gemini/mcp_memory/clipboard"); - let _ = std::fs::create_dir_all(&cache_dir); - let file_path = cache_dir.join("clipboard_latest_image.jpg"); - if std::fs::write(&file_path, &bytes).is_ok() { - let path_str = file_path.to_string_lossy().to_string(); - out.insert("image_path".into(), json!(path_str)); - let wsl_path = to_wsl_path(&path_str); - out.insert("image_path_wsl".into(), json!(wsl_path)); - } - } - - if let Some(eng) = engine - && let Some(ocr_text) = perform_ocrs_ocr(eng, &dynamic_img) - { - out.insert("image_analysis".to_string(), json!(ocr_text.trim())); - } - } - Ok(out) - }, - ) - .await - .map_err(|e| crate::error::AppError::Internal(format!("Task panic: {}", e)))??; - - state.record_activity("clipboard", "Read contents from OS clipboard", None); - Ok::(serde_yaml::to_string(&Value::Object(out))?) - } ClipboardAction::Write => { let text_opt = req.text; let image_path_opt = req.image_path; @@ -1023,38 +961,7 @@ mod tests { ); } - #[tokio::test] - async fn test_read_clipboard() { - let dir = tempdir().unwrap(); - let state = Arc::new(MemoryState::new(dir.path().to_str().unwrap())); - let handler = ClipboardHandler; - let result = handler - .execute(json!({"action": "read"}), state) - .await - .map_err(|e| format!("Failed to read clipboard: {}", e)) - .unwrap(); - - // Returns a JSON string, possibly {} - let parsed: serde_json::Value = serde_yaml::from_str(&result).unwrap(); - assert!(parsed.is_object()); - } - - #[tokio::test] - async fn test_read_clipboard_empty() { - let dir = tempfile::tempdir().unwrap(); - let state = Arc::new(MemoryState::new(dir.path().to_str().unwrap())); - let handler = ClipboardHandler; - - let result = handler - .execute(serde_json::json!({"action": "read"}), state) - .await - .map_err(|e| format!("Failed to read clipboard: {}", e)) - .unwrap(); - - let parsed: serde_json::Value = serde_yaml::from_str(&result).unwrap(); - assert!(parsed.is_object()); - } #[test] fn test_no_subprocess_clipboard_regression() { diff --git a/server/src/instructions.md b/server/src/instructions.md index ed7e611..f63bc32 100644 --- a/server/src/instructions.md +++ b/server/src/instructions.md @@ -59,7 +59,7 @@ The server registers 5 high-signal workflow prompts to initiate standardized age ## 5. Consolidated Smart Tools Architecture (11 Primary Tools) -The server consolidates granular single-purpose tools into domain-named smart tools. Always prefer the consolidated tools over legacy aliases: +The server consolidates granular single-purpose tools into domain-named smart tools. * **`tasks`**: Complete task lifecycle management. - `action: "add"`: Create a new task (requires `title`, optional `description`, `git_branch`, `repo_name`, `priority: "low" | "medium" | "high" | "urgent"`, `assigned_agent`, `verification_command`, `parent_id`, `dependencies`). diff --git a/server/src/router.rs b/server/src/router.rs index b79453f..b4ac37b 100644 --- a/server/src/router.rs +++ b/server/src/router.rs @@ -1428,7 +1428,7 @@ mod tests { ("decisions", json!({"action": "query"})), ("tech_debt", json!({"action": "list"})), ("snippets", json!({"action": "search", "query": "test"})), - ("clipboard", json!({"action": "read"})), + ("clipboard", json!({"action": "history"})), ("environment", json!({"action": "read_fingerprint"})), ("omni_search", json!({"query": "test"})), ("get_project_health", json!({})), diff --git a/server/src/tools.rs b/server/src/tools.rs index 88e2960..4a1a002 100644 --- a/server/src/tools.rs +++ b/server/src/tools.rs @@ -172,8 +172,6 @@ pub enum SubgraphFormat { pub struct GetSubgraphTool { /// The root entity name to start the subgraph search from. pub root_entity: Option, - /// Legacy alias for root_entity. - pub root_node: Option, /// Maximum search depth (hops). Defaults to 2. pub depth: Option, /// Output format: 'json' (raw entities and relations) or 'markdown_tree' (compact topology tree). Defaults to 'json'. @@ -1014,8 +1012,6 @@ pub enum ClipboardAction { History, #[serde(alias = "clear", alias = "CLEAR", alias = "Clear")] Clear, - #[serde(alias = "read", alias = "READ", alias = "Read")] - Read, #[serde(alias = "write", alias = "WRITE", alias = "Write")] Write, } @@ -1026,7 +1022,6 @@ pub enum ClipboardAction { /// - 'text': Get latest clipboard text (or normalized Markdown if HTML was copied). /// - 'history': View recent clipboard history ring buffer (images and text with timestamps). /// - 'clear': Clear OS clipboard and memory cache. -/// - 'read': Read current clipboard contents (legacy alias). /// - 'write': Write content to OS clipboard. Optional: text, html, files, image_path. /// /// Triggers: Call 'image' immediately when user says "look at image in clipboard", "see screenshot",