diff --git a/.luarc.json b/.luarc.json index 6779f74..f5ab2a7 100644 --- a/.luarc.json +++ b/.luarc.json @@ -1,5 +1,11 @@ { "diagnostics.disable": [ "missing-fields" + ], + "diagnostics.globals": [ + "vim", + "make_avante_system_prompt", + "update_avante_system_prompt", + "get_server_list_prompt" ] } \ No newline at end of file diff --git a/nix/base-system/init.lua b/nix/base-system/init.lua index 1924fb8..12623c9 100644 --- a/nix/base-system/init.lua +++ b/nix/base-system/init.lua @@ -32,15 +32,15 @@ vim.cmd("noswapfile") vim.cmd("syntax on") vim.cmd("filetype plugin on") -vim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter"}, { - pattern = {"*.qnt"}, - callback = function(args) +vim.api.nvim_create_autocmd({ "BufEnter", "BufWinEnter" }, { + pattern = { "*.qnt" }, + callback = function(args) vim.lsp.start({ name = 'quint', - cmd = {'quint-language-server', '--stdio'}, + cmd = { 'quint-language-server', '--stdio' }, root_dir = vim.fs.dirname(vim.uri_from_bufnr(args.buf)) }) - end, + end, }) vim.cmd([[ @@ -76,7 +76,7 @@ au BufNewFile,BufRead *.hrl filetype indent off ]]) vim.cmd([[ -au BufNewFile,BufRead *.nix set tabstop=2 nosmarttab +au BufNewFile,BufRead *.nix set tabstop=2 nosmarttab ]]) vim.cmd([[ @@ -148,7 +148,7 @@ local caps = vim.tbl_deep_extend( local lspconfig = require("lspconfig") -- Typst -lspconfig.tinymist.setup{ +lspconfig.tinymist.setup { capabilities = caps, settings = { exportPdf = "onSave", @@ -163,11 +163,11 @@ lspconfig.nil_ls.setup { capabilities = caps, } -lspconfig.jedi_language_server.setup{} +lspconfig.jedi_language_server.setup {} require('roslyn').setup({ -- client, bufnr - on_attach = function (_, _) + on_attach = function(_, _) --vim.notify(vim.inspect(client)) end, sdk_framework = "net8.0", @@ -234,7 +234,7 @@ vim.api.nvim_create_autocmd('LspAttach', { vim.keymap.set({ "n", "v" }, "a", vim.lsp.buf.code_action, opts) vim.keymap.set("n", "f", vim.lsp.buf.format, opts) local client = vim.lsp.get_client_by_id(args.data.client_id) ----@diagnostic disable-next-line: undefined-field + ---@diagnostic disable-next-line: undefined-field if client and client.server_capabilities.codelens then vim.lsp.codelens.refresh() end @@ -243,9 +243,9 @@ vim.api.nvim_create_autocmd('LspAttach', { vim.api.nvim_create_autocmd({ 'BufEnter', 'InsertLeave', 'CursorHold' }, { callback = function(args) - local clients = vim.lsp.get_clients({bufnr=args.buf}) + local clients = vim.lsp.get_clients({ bufnr = args.buf }) for cid = 1, #clients do ----@diagnostic disable-next-line: undefined-field + ---@diagnostic disable-next-line: undefined-field if clients[cid].server_capabilities.codelens then vim.lsp.codelens.refresh() break @@ -529,7 +529,7 @@ lean.setup { vim.keymap.set({ "n", "v" }, "ti", function() vim.cmd("LeanInfoviewToggle") end, opts) vim.keymap.set({ "n", "v" }, "sg", function() vim.cmd("LeanGoal") end, opts) vim.keymap.set({ "n", "v" }, "stg", function() vim.cmd("LeanTermGoal") end, opts) - vim.api.nvim_set_option_value('omnifunc', 'v:lua.vim.lsp.omnifunc', {scope = "local", buf=bufnr}) + vim.api.nvim_set_option_value('omnifunc', 'v:lua.vim.lsp.omnifunc', { scope = "local", buf = bufnr }) end }, mappings = true, @@ -545,8 +545,10 @@ vim.keymap.set("n", "rn", vim.lsp.buf.rename) vim.keymap.set("n", "sl", telescope_builtins.lsp_workspace_symbols) vim.keymap.set("n", "dl", telescope_builtins.diagnostics) vim.keymap.set("n", "rg", telescope_builtins.live_grep) -vim.keymap.set("n", "bl", function() telescope_builtins.buffers({ -}) end) +vim.keymap.set("n", "bl", function() + telescope_builtins.buffers({ + }) +end) vim.keymap.set("n", "lds", telescope_builtins.lsp_document_symbols, { desc = "[D]ocument [S]ymbols" }) vim.keymap.set("n", "lws", telescope_builtins.lsp_dynamic_workspace_symbols, { desc = "[W]orkspace [S]ymbols" }) @@ -572,67 +574,67 @@ require('lualine').setup { }, sections = { -- left side - lualine_a = {'mode'}, - lualine_b = {'filename'}, - lualine_c = {'encoding', 'fileformat', 'filetype'}, + lualine_a = { 'mode' }, + lualine_b = { 'filename' }, + lualine_c = { 'encoding', 'fileformat', 'filetype' }, -- right side - lualine_x = {'diagnostics'}, - lualine_y = {'progress', 'lsp_progress'}, - lualine_z = {'location'} + lualine_x = { 'diagnostics' }, + lualine_y = { 'progress', 'lsp_progress' }, + lualine_z = { 'location' } } } -- Hunk diff tree viewer and editor. Replacement for Meld and company local hunk = require("hunk") hunk.setup({ - keys = { - global = { - quit = { "q" }, - accept = { "" }, - focus_tree = { "e" }, + keys = { + global = { + quit = { "q" }, + accept = { "" }, + focus_tree = { "e" }, + }, + + tree = { + expand_node = { "l", "" }, + collapse_node = { "h", "" }, + + open_file = { "" }, + + toggle_file = { "a" }, + }, + + diff = { + toggle_line = { "a" }, + toggle_hunk = { "A" }, + }, }, - tree = { - expand_node = { "l", "" }, - collapse_node = { "h", "" }, - - open_file = { "" }, - - toggle_file = { "a" }, + ui = { + tree = { + -- Mode can either be `nested` or `flat` + mode = "nested", + width = 35, + }, + --- Can be either `vertical` or `horizontal` + layout = "vertical", }, - diff = { - toggle_line = { "a" }, - toggle_hunk = { "A" }, + icons = { + selected = "󰡖", + deselected = "", + partially_selected = "󰛲", + + folder_open = "", + folder_closed = "", }, - }, - ui = { - tree = { - -- Mode can either be `nested` or `flat` - mode = "nested", - width = 35, - }, - --- Can be either `vertical` or `horizontal` - layout = "vertical", - }, - - icons = { - selected = "󰡖", - deselected = "", - partially_selected = "󰛲", - - folder_open = "", - folder_closed = "", - }, - - -- Called right after each window and buffer are created. - --hooks = { - -- ---@param _context { buf: number, tree: NuiTree, opts: table } - -- on_tree_mount = function(_context) end, - -- ---@param _context { buf: number, win: number } - -- on_diff_mount = function(_context) end, - --}, + -- Called right after each window and buffer are created. + --hooks = { + -- ---@param _context { buf: number, tree: NuiTree, opts: table } + -- on_tree_mount = function(_context) end, + -- ---@param _context { buf: number, win: number } + -- on_diff_mount = function(_context) end, + --}, }) local dap = require('dap') @@ -678,47 +680,91 @@ local mcphub = require("mcphub") mcphub.setup({ -- This sets vim.g.mcphub_auto_approve to false by default (can also be toggled from the HUB UI with `ga`) config = vim.fn.expand("~/.config/mcphub/servers.json"), - auto_approve = false, + auto_approve = true, auto_toggle_mcp_servers = true, -- Let LLMs start and stop MCP servers automatically extensions = { avante = { make_slash_commands = true, -- make /slash commands from MCP server prompts - } + }, }, - cmd = "mcp-hub"; + cmd = "mcp-hub", }) -local hub_instance = mcphub.get_hub_instance(); +function get_server_list_prompt(hub_instance) + -- returns a list of mcp-servers with a `name` and a list of tools with `name` + local mcp_tool_prompt = "# MCP SERVERS\n\nThe Model Context Protocol (MCP) enables communication between the system and locally running MCP servers that provide additional tools and resources to extend your capabilities.\n\n# Connected MCP Servers\n\nWhen a server is connected, you can use the server's tools via the `use_mcp_tool` tool, and access the server's resources via the `access_mcp_resource` tool.\nNote: Server names are case sensitive and you should always use the exact full name like `Firecrawl MCP` or `src/user/main/time-mcp` etc\n\n" + + if not hub_instance then + return "" + end + + local servers = hub_instance:get_servers() + if not servers or #servers == 0 then + return "" + end + + for _, server in ipairs(servers) do + mcp_tool_prompt = mcp_tool_prompt .. "## server name: `" .. server.name .. "`\n\n" + + if server.capabilities.tools and #server.capabilities.tools > 0 then + mcp_tool_prompt = mcp_tool_prompt .. "Available tools:\n\n" + for _, tool in ipairs(server.capabilities.tools) do + mcp_tool_prompt = mcp_tool_prompt .. "- tool name: `" .. tool.name .. "`\n" + if tool.description then + mcp_tool_prompt = mcp_tool_prompt .. " - Description: " .. tool.description .. "\n" + end + end + mcp_tool_prompt = mcp_tool_prompt .. "\n" + end + end + + return mcp_tool_prompt +end + +function make_avante_system_prompt(hub_instance) + return hub_instance and get_server_list_prompt(hub_instance) or "" +end + +function update_avante_system_prompt() + local hub_instance = mcphub.get_hub_instance(); + local system_prompt = make_avante_system_prompt(hub_instance) + if system_prompt then + require("avante.config").override({system_prompt = system_prompt}) + end +end require('copilot').setup(); -require('avante').setup ({ +require('avante').setup({ provider = "claude", - mode = "agentic", - cursor_applying_provider = nil, -- default to whatever provide is configured + mode = "planning", + cursor_applying_provider = nil, -- default to whatever provider is configured claude = { - endpoint = "https://api.anthropic.com", - model = "claude-3-7-sonnet-20250219", - timeout = 30000, -- Timeout in milliseconds - temperature = 0, - max_tokens = 20480, + endpoint = "https://api.anthropic.com", + model = "claude-3-7-sonnet-20250219", + timeout = 30000, -- Timeout in milliseconds + temperature = 0, + max_tokens = 20480, + }, + copilot = { + model = "claude-3.7-sonnet", }, behavior = { enable_cursor_planning_mode = true, }, - system_prompt = hub_instance and hub_instance:get_active_servers_prompt() or "", + system_prompt = make_avante_system_prompt(mcphub.get_hub_instance()), custom_tools = { require("mcphub.extensions.avante").mcp_tool() }, -- Disable these because we'll use the mcphub versions instead - disabled_tools = { - "list_files", -- Built-in file operations - "search_files", - "read_file", - "create_file", - "rename_file", - "delete_file", - "create_dir", - "rename_dir", - "delete_dir", - "bash", -- Built-in terminal access - }, + --disabled_tools = { + -- "list_files", -- Built-in file operations + -- "search_files", + -- "read_file", + -- "create_file", + -- "rename_file", + -- "delete_file", + -- "create_dir", + -- "rename_dir", + -- "delete_dir", + -- "bash", -- Built-in terminal access + --}, })