Skip to content
This repository was archived by the owner on Jan 14, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 17 additions & 51 deletions lua/codecompanion/_extensions/gitcommit/tools/ai_release_notes.lua
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
local prompts = require("codecompanion._extensions.gitcommit.prompts.release_notes")

---@class CodeCompanion.GitCommit.Tools.AIReleaseNotes
---@class CodeCompanion.GitCommit.Tools.AIReleaseNotes: CodeCompanion.Tools.Tool
local AIReleaseNotes = {}

AIReleaseNotes.name = "ai_release_notes"
AIReleaseNotes.description = "Generate comprehensive release notes using AI analysis of commit history"

AIReleaseNotes.schema = {
type = "function",
Expand Down Expand Up @@ -194,77 +193,44 @@ AIReleaseNotes.cmds = {
-- Get detailed commit history
local commits, error_msg = get_detailed_commits(from_tag, to_tag)
if not commits then
return {
status = "error",
data = {
output = error_msg,
user_msg = "✗ " .. error_msg,
llm_msg = "<aiReleaseNotes>fail: " .. error_msg .. "</aiReleaseNotes>",
},
}
return { status = "error", data = error_msg }
end

if #commits == 0 then
local msg = string.format("No commits found between %s and %s", from_tag, to_tag)
return {
status = "success",
data = {
output = msg,
user_msg = "ℹ " .. msg,
llm_msg = "<aiReleaseNotes>success: " .. msg .. "</aiReleaseNotes>",
},
}
return { status = "success", data = msg }
end

local prompt = prompts.create_smart_prompt(commits, style, { from = from_tag, to = to_tag })

local user_msg =
string.format("📝 Generating %s release notes: %s → %s (%d commits)", style, from_tag, to_tag, #commits)

local llm_msg = string.format("<aiReleaseNotes>\n%s\n</aiReleaseNotes>", prompt)

return {
status = "success",
data = {
output = prompt,
user_msg = user_msg,
llm_msg = llm_msg,
},
}
return { status = "success", data = prompt }
end,
}

AIReleaseNotes.handlers = {
setup = function(_self, _agent)
return true
end,
on_exit = function(_self, _agent) end,
on_exit = function(self, tools) end,
}

AIReleaseNotes.output = {
success = function(self, agent, _cmd, stdout)
local chat = agent.chat
local data = stdout[1]
local llm_msg = data and data.llm_msg or data.output
local user_msg = data and data.user_msg or data.output
return chat:add_tool_output(self, llm_msg, user_msg)
success = function(self, tools, cmd, stdout)
local chat = tools.chat
local output = stdout and #stdout > 0 and vim.iter(stdout):flatten():join("\n") or ""
local user_msg = "Release notes generated"
chat:add_tool_output(self, output, user_msg)
end,
error = function(self, agent, _cmd, stderr, stdout)
local chat = agent.chat
local data = stderr[1] or stdout[1]
local llm_msg = data and data.llm_msg or (type(data) == "string" and data or "AI release notes generation failed")
local user_msg = data and data.user_msg or "AI release notes generation failed"
return chat:add_tool_output(self, llm_msg, user_msg)
error = function(self, tools, cmd, stderr, stdout)
local chat = tools.chat
local errors = stderr and #stderr > 0 and vim.iter(stderr):flatten():join("\n") or "Unknown error"
local user_msg = "Release notes generation failed"
chat:add_tool_output(self, errors, user_msg)
end,
Comment on lines 194 to 226

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This refactoring has removed the detailed user messages for both success and error cases, replacing them with generic strings. This is a regression in user experience. For example, the user no longer sees which tags are being used for release notes generation.

To restore this valuable feedback, the cmds function can return a table containing the necessary information, and the output handlers can be updated to use it. This will make the tool's feedback much more informative.

    local commits, error_msg = get_detailed_commits(from_tag, to_tag)
    if not commits then
      return { status = "error", data = { user_msg = "✗ " .. error_msg, output = error_msg } }
    end

    if #commits == 0 then
      local msg = string.format("No commits found between %s and %s", from_tag, to_tag)
      return { status = "success", data = { user_msg = "ℹ " .. msg, output = msg } }
    end

    local prompt = prompts.create_smart_prompt(commits, style, { from = from_tag, to = to_tag })
    local user_msg = string.format("📝 Generating %s release notes: %s → %s (%d commits)", style, from_tag, to_tag, #commits)

    return { status = "success", data = { output = prompt, user_msg = user_msg } }
  end,
}

AIReleaseNotes.handlers = {
  on_exit = function(self, tools) end,
}

AIReleaseNotes.output = {
  success = function(self, tools, cmd, stdout)
    local chat = tools.chat
    local data = stdout and stdout[1]
    local output, user_msg
    if type(data) == "table" and data.output then
      output = data.output
      user_msg = data.user_msg or "Release notes generated"
    else
      output = stdout and #stdout > 0 and vim.iter(stdout):flatten():join("\n") or ""
      user_msg = "Release notes generated"
    end
    chat:add_tool_output(self, output, user_msg)
  end,
  error = function(self, tools, cmd, stderr, stdout)
    local chat = tools.chat
    local data = stderr and stderr[1] or (stdout and stdout[1])
    local output, user_msg
    if type(data) == "table" and data.output then
      output = data.output
      user_msg = data.user_msg or "AI release notes generation failed"
    else
      output = stderr and #stderr > 0 and vim.iter(stderr):flatten():join("\n") or "Unknown error"
      user_msg = "AI release notes generation failed"
    end
    chat:add_tool_output(self, output, user_msg)
  end,

}

AIReleaseNotes.opts = {
-- v18+ uses require_approval_before
require_approval_before = function(_self, _agent)
require_approval_before = function(self, tools)
return false
end,
-- COMPAT(v17): Remove when dropping v17 support
requires_approval = function(_self, _agent)
requires_approval = function(self, tools)
return false
end,
}
Expand Down
Loading