diff --git a/lua/opencode/ui/formatter/tools/init.lua b/lua/opencode/ui/formatter/tools/init.lua index 91d786ff..8c23a5b0 100644 --- a/lua/opencode/ui/formatter/tools/init.lua +++ b/lua/opencode/ui/formatter/tools/init.lua @@ -10,6 +10,7 @@ return { webfetch = require('opencode.ui.formatter.tools.webfetch'), list = require('opencode.ui.formatter.tools.list'), question = require('opencode.ui.formatter.tools.question'), + skill = require('opencode.ui.formatter.tools.skill'), task = require('opencode.ui.formatter.tools.task'), tool = require('opencode.ui.formatter.tools.tool'), } diff --git a/lua/opencode/ui/formatter/tools/skill.lua b/lua/opencode/ui/formatter/tools/skill.lua new file mode 100644 index 00000000..02151460 --- /dev/null +++ b/lua/opencode/ui/formatter/tools/skill.lua @@ -0,0 +1,20 @@ +local icons = require('opencode.ui.icons') +local utils = require('opencode.ui.formatter.utils') + +local M = {} + +---@param output Output +---@param part OpencodeMessagePart +function M.format(output, part) + local input = part.state and part.state.input or {} + utils.format_action(output, icons.get('skill'), 'skill', input.name or '', utils.get_duration_text(part)) +end + +---@param _ OpencodeMessagePart +---@param input table +---@return string, string, string +function M.summary(_, input) + return icons.get('skill'), 'skill', input.name or '' +end + +return M diff --git a/lua/opencode/ui/icons.lua b/lua/opencode/ui/icons.lua index 01364e18..54066cc2 100644 --- a/lua/opencode/ui/icons.lua +++ b/lua/opencode/ui/icons.lua @@ -19,6 +19,7 @@ local presets = { web = '󰖟 ', list = ' ', tool = ' ', + skill = '󰐱 ', snapshot = '󰻛 ', restore_point = '󱗚 ', file = ' ', @@ -64,6 +65,7 @@ local presets = { web = '::', list = '::', tool = '::', + skill = '::', snapshot = '::', restore_point = '::', file = '@', diff --git a/tests/unit/formatter_spec.lua b/tests/unit/formatter_spec.lua index 830db8c9..6d474591 100644 --- a/tests/unit/formatter_spec.lua +++ b/tests/unit/formatter_spec.lua @@ -202,6 +202,40 @@ describe('formatter', function() assert.is_true(found) end) + it('renders loaded skill name for skill tool calls', function() + local message = { + info = { + id = 'msg_1', + role = 'assistant', + sessionID = 'ses_1', + }, + parts = {}, + } + + local part = { + id = 'prt_1', + type = 'tool', + tool = 'skill', + messageID = 'msg_1', + sessionID = 'ses_1', + state = { + status = 'completed', + input = { + name = 'context7-cli', + }, + time = { + start = 1, + ['end'] = 2, + }, + }, + } + + local output = formatter.format_part(part, message, true) + + assert.is_truthy(output.lines[1]:find('skill', 1, true)) + assert.is_truthy(output.lines[1]:find('context7%-cli')) + end) + it('renders directory reads with trailing slash', function() local message = { info = {