feat: parse and conditionally add cursor rules to system prompt (#2385)

This commit is contained in:
Peter Cardenas
2025-07-01 09:59:01 -07:00
committed by GitHub
parent f523710e95
commit 2ecfe587a0
2 changed files with 50 additions and 0 deletions

View File

@@ -388,6 +388,8 @@ function M.generate_prompts(opts)
local agents_rules = Prompts.get_agents_rules_prompt()
if agents_rules then system_prompt = system_prompt .. "\n\n" .. agents_rules end
local cursor_rules = Prompts.get_cursor_rules_prompt(selected_files)
if cursor_rules then system_prompt = system_prompt .. "\n\n" .. cursor_rules end
---@type AvantePromptOptions
return {

View File

@@ -233,4 +233,52 @@ function M.get_agents_rules_prompt()
return nil
end
---@param selected_files AvanteSelectedFile[]
---@return string | nil
function M.get_cursor_rules_prompt(selected_files)
local Utils = require("avante.utils")
local project_root = Utils.get_project_root()
local accumulated_content = ""
---@type string[]
local mdc_files = vim.fn.globpath(Utils.join_paths(project_root, ".cursor/rules"), "*.mdc", false, true)
for _, file_path in ipairs(mdc_files) do
---@type string[]
local content = vim.fn.readfile(file_path)
if content[1] ~= "---" or content[5] ~= "---" then goto continue end
local header, body = table.concat(content, "\n", 2, 4), table.concat(content, "\n", 6)
local _description, globs, alwaysApply = header:match("description:%s*(.*)\nglobs:%s*(.*)\nalwaysApply:%s*(.*)")
if not globs then goto continue end
globs = vim.trim(globs)
-- TODO: When empty string, this means the agent should request for this rule ad-hoc.
if globs == "" then goto continue end
local globs_array = vim.split(globs, ",%s*")
local path_regexes = {} ---@type string[]
for _, glob in ipairs(globs_array) do
path_regexes[#path_regexes + 1] = glob:gsub("%*%*", ".+"):gsub("%*", "[^/]*")
path_regexes[#path_regexes + 1] = glob:gsub("%*%*/", ""):gsub("%*", "[^/]*")
end
local always_apply = alwaysApply == "true"
if always_apply then
accumulated_content = accumulated_content .. "\n" .. body
else
local matched = false
for _, selected_file in ipairs(selected_files) do
for _, path_regex in ipairs(path_regexes) do
if string.match(selected_file.path, path_regex) then
accumulated_content = accumulated_content .. "\n" .. body
matched = true
break
end
end
if matched then break end
end
end
::continue::
end
return accumulated_content ~= "" and accumulated_content or nil
end
return M