Skip to content

Commit 7306c13

Browse files
committed
fix(formatter/grep): normalize grep input handling
Normalize parts in resolve_grep_string to safely convert nil, vim.NIL, numbers, and booleans to strings and prefer input.path over input.include when present. This prevents invalid grep strings from non-string inputs.
1 parent b9a201c commit 7306c13

2 files changed

Lines changed: 60 additions & 2 deletions

File tree

lua/opencode/ui/formatter/tools/grep.lua

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,30 @@ local M = {}
44
---@param input GrepToolInput|nil
55
---@return string
66
local function resolve_grep_string(input)
7+
local function normalize_part(value)
8+
if value == nil or value == vim.NIL then
9+
return ''
10+
end
11+
12+
local value_type = type(value)
13+
if value_type == 'string' then
14+
return value
15+
end
16+
if value_type == 'number' or value_type == 'boolean' then
17+
return tostring(value)
18+
end
19+
20+
return ''
21+
end
22+
723
if not input then
824
return ''
925
end
10-
local path_part = input.path or input.include or ''
11-
local pattern_part = input.pattern or ''
26+
local path_part = normalize_part(input.path)
27+
if path_part == '' then
28+
path_part = normalize_part(input.include)
29+
end
30+
local pattern_part = normalize_part(input.pattern)
1231
return table.concat(
1332
vim.tbl_filter(function(p)
1433
return p ~= nil and p ~= ''

tests/unit/formatter_spec.lua

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,4 +199,43 @@ describe('formatter', function()
199199
assert.are.equal('+', add_mark.virt_text[2][1])
200200
assert.are.equal('OpencodeDiffAddGutter', add_mark.virt_text[1][2])
201201
end)
202+
203+
it('formats grep tools when streamed input contains vim.NIL placeholders', function()
204+
local message = {
205+
info = {
206+
id = 'msg_1',
207+
role = 'assistant',
208+
sessionID = 'ses_1',
209+
},
210+
parts = {},
211+
}
212+
213+
local part = {
214+
id = 'prt_grep_1',
215+
type = 'tool',
216+
tool = 'grep',
217+
messageID = 'msg_1',
218+
sessionID = 'ses_1',
219+
state = {
220+
status = 'completed',
221+
input = {
222+
path = vim.NIL,
223+
include = '*.lua',
224+
pattern = 'eventignore',
225+
},
226+
metadata = {
227+
matches = 3,
228+
},
229+
time = {
230+
start = 1,
231+
['end'] = 2,
232+
},
233+
},
234+
}
235+
236+
local output = formatter.format_part(part, message, true)
237+
238+
assert.are.equal('** grep** `*.lua eventignore` 1s', output.lines[1])
239+
assert.are.equal('Found `3` matches', output.lines[2])
240+
end)
202241
end)

0 commit comments

Comments
 (0)