fix(mcp): Add missing Cargo.lock, lua bindings, and workspace fixes for tools
This commit is contained in:
1 parent
c1b9767199
commit
185c3c999e
4 files changed
+154
-1
No files matched your search
Generated
+44
@@ -2130,6 +2130,10 @@ dependencies = [
|
|||||||
"tracing-appender",
|
"tracing-appender",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"tree-sitter",
|
"tree-sitter",
|
||||||
|
"tree-sitter-c",
|
||||||
|
"tree-sitter-cpp",
|
||||||
|
"tree-sitter-go",
|
||||||
|
"tree-sitter-java",
|
||||||
"tree-sitter-python",
|
"tree-sitter-python",
|
||||||
"tree-sitter-rust",
|
"tree-sitter-rust",
|
||||||
"tree-sitter-typescript",
|
"tree-sitter-typescript",
|
||||||
@@ -4209,6 +4213,46 @@ dependencies = [
|
|||||||
"tree-sitter-language",
|
"tree-sitter-language",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tree-sitter-c"
|
||||||
|
version = "0.24.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9b2eb57a55fed6b00812912e730b7a275cf4fe98bfd6a5d76263d4438371728"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"tree-sitter-language",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tree-sitter-cpp"
|
||||||
|
version = "0.23.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "df2196ea9d47b4ab4a31b9297eaa5a5d19a0b121dceb9f118f6790ad0ab94743"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"tree-sitter-language",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tree-sitter-go"
|
||||||
|
version = "0.25.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c8560a4d2f835cc0d4d2c2e03cbd0dde2f6114b43bc491164238d333e28b16ea"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"tree-sitter-language",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tree-sitter-java"
|
||||||
|
version = "0.23.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0aa6cbcdc8c679b214e616fd3300da67da0e492e066df01bcf5a5921a71e90d6"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"tree-sitter-language",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tree-sitter-language"
|
name = "tree-sitter-language"
|
||||||
version = "0.1.8"
|
version = "0.1.8"
|
||||||
|
|||||||
@@ -197,4 +197,38 @@ function M.setup()
|
|||||||
vim.keymap.set('n', '<leader>ar', M.reject_diff, { desc = "Reject Agent Diff", noremap = true, silent = true })
|
vim.keymap.set('n', '<leader>ar', M.reject_diff, { desc = "Reject Agent Diff", noremap = true, silent = true })
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function M.send_to_terminal(command)
|
||||||
|
local term_buf = nil
|
||||||
|
for _, buf in ipairs(vim.api.nvim_list_bufs()) do
|
||||||
|
if vim.api.nvim_buf_is_loaded(buf) and vim.bo[buf].buftype == "terminal" then
|
||||||
|
term_buf = buf
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not term_buf then
|
||||||
|
vim.cmd("split | term")
|
||||||
|
term_buf = vim.api.nvim_get_current_buf()
|
||||||
|
else
|
||||||
|
local win_found = false
|
||||||
|
for _, win in ipairs(vim.api.nvim_list_wins()) do
|
||||||
|
if vim.api.nvim_win_get_buf(win) == term_buf then
|
||||||
|
vim.api.nvim_set_current_win(win)
|
||||||
|
win_found = true
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not win_found then
|
||||||
|
vim.cmd("split")
|
||||||
|
vim.api.nvim_win_set_buf(0, term_buf)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local job_id = vim.b[term_buf].terminal_job_id
|
||||||
|
if job_id then
|
||||||
|
vim.api.nvim_chan_send(job_id, command .. "\r\n")
|
||||||
|
vim.api.nvim_win_set_cursor(0, {vim.api.nvim_buf_line_count(term_buf), 0})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return M
|
return M
|
||||||
@@ -1118,6 +1118,31 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {}
|
"properties": {}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "nvim_send_to_terminal",
|
||||||
|
"description": "Send a given command string to a Neovim split terminal.",
|
||||||
|
"inputSchema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"command": { "type": "string" }
|
||||||
|
},
|
||||||
|
"required": ["command"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "nvim_set_preview",
|
||||||
|
"description": "Overlay proposed code changes as Ghost Text. The preview mechanism uses extmarks for inline suggestions.",
|
||||||
|
"inputSchema": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"file_path": { "type": "string" },
|
||||||
|
"start_line": { "type": "integer" },
|
||||||
|
"end_line": { "type": "integer" },
|
||||||
|
"preview_content": { "type": "string" }
|
||||||
|
},
|
||||||
|
"required": ["file_path", "start_line", "end_line", "preview_content"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})),
|
})),
|
||||||
@@ -1574,6 +1599,56 @@ pub async fn run_mcp_loop(app_name: &str, app_version: &str) {
|
|||||||
send_error(id, -32602, "Missing 'code'").await;
|
send_error(id, -32602, "Missing 'code'").await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"nvim_send_to_terminal" => {
|
||||||
|
if let Some(cmd) = args.get("command").and_then(|v| v.as_str()) {
|
||||||
|
let escaped_cmd = cmd.replace('\\', "\\\\").replace('"', "\\\"");
|
||||||
|
let lua_code = format!(r#"
|
||||||
|
if _G.gemini and _G.gemini.send_to_terminal then
|
||||||
|
_G.gemini.send_to_terminal("{escaped_cmd}")
|
||||||
|
return "Command sent to terminal"
|
||||||
|
else
|
||||||
|
error("gemini UI not loaded")
|
||||||
|
end
|
||||||
|
"#);
|
||||||
|
handle_lua_result!(id, execute_nvim_lua(&lua_code));
|
||||||
|
} else {
|
||||||
|
send_error(id, -32602, "Missing 'command'").await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"nvim_set_preview" => {
|
||||||
|
if let (Some(file), Some(start_line), Some(end_line), Some(preview_content)) = (
|
||||||
|
args.get("file_path").and_then(|v| v.as_str()),
|
||||||
|
args.get("start_line").and_then(|v| v.as_i64()),
|
||||||
|
args.get("end_line").and_then(|v| v.as_i64()),
|
||||||
|
args.get("preview_content").and_then(|v| v.as_str())
|
||||||
|
) {
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
let diff_id = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_millis().to_string();
|
||||||
|
|
||||||
|
let mut lines_str = String::from("{");
|
||||||
|
for line in preview_content.lines() {
|
||||||
|
lines_str.push_str(&format!(r#""{}", "#, line.replace('\\', "\\\\").replace('"', "\\\"")));
|
||||||
|
}
|
||||||
|
lines_str.push('}');
|
||||||
|
|
||||||
|
let escaped_file = file.replace('\\', "\\\\").replace('"', "\\\"");
|
||||||
|
let lua_code = format!(r#"
|
||||||
|
if _G.gemini and _G.gemini.preview_diff then
|
||||||
|
local bufnr = vim.fn.bufnr("{escaped_file}")
|
||||||
|
if bufnr == -1 then
|
||||||
|
bufnr = 0
|
||||||
|
end
|
||||||
|
_G.gemini.preview_diff("{diff_id}", bufnr, {start_line}, {end_line}, {lines_str})
|
||||||
|
return "Preview added"
|
||||||
|
else
|
||||||
|
error("gemini UI not loaded")
|
||||||
|
end
|
||||||
|
"#);
|
||||||
|
handle_lua_result!(id, execute_nvim_lua(&lua_code));
|
||||||
|
} else {
|
||||||
|
send_error(id, -32602, "Missing arguments").await;
|
||||||
|
}
|
||||||
|
}
|
||||||
"nvim_get_server_info" => {
|
"nvim_get_server_info" => {
|
||||||
let os = if cfg!(windows) { "Windows" } else { "Linux" };
|
let os = if cfg!(windows) { "Windows" } else { "Linux" };
|
||||||
let exe_path = std::env::current_exe()
|
let exe_path = std::env::current_exe()
|
||||||
|
|||||||
@@ -543,7 +543,7 @@ impl McpTool for ReadDirectoryArchitectureHandler {
|
|||||||
|
|
||||||
fn visit_dirs(dir: &std::path::Path, summary: &mut String, depth: usize) -> std::io::Result<()> {
|
fn visit_dirs(dir: &std::path::Path, summary: &mut String, depth: usize) -> std::io::Result<()> {
|
||||||
if dir.is_dir() {
|
if dir.is_dir() {
|
||||||
let mut entries = fs::read_dir(dir)?.collect::<Result<Vec<_>, std::io::Result<_>>>()?;
|
let mut entries = fs::read_dir(dir)?.collect::<Result<Vec<_>, std::io::Error>>()?;
|
||||||
entries.sort_by_key(|e| e.path());
|
entries.sort_by_key(|e| e.path());
|
||||||
|
|
||||||
for entry in entries {
|
for entry in entries {
|
||||||
|
|||||||
Reference in new issue
Block a user