From d6c00967f07b4a48cd0309c6e4daf01e0aab965b Mon Sep 17 00:00:00 2001 From: Francis Belanger Date: Wed, 14 Jan 2026 11:13:15 -0500 Subject: [PATCH] feat(api): add '/review' command for code review checklist and diff/PR review --- lua/opencode/api.lua | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/lua/opencode/api.lua b/lua/opencode/api.lua index c85947de..60f2cbde 100644 --- a/lua/opencode/api.lua +++ b/lua/opencode/api.lua @@ -941,6 +941,39 @@ function M.toggle_reasoning_output() ui.render_output() end +---@type fun(): Promise +M.review = Promise.async(function(args) + local id = require('opencode.id') + + local new_session = core.create_new_session('Code review checklist for diffs and PRs'):await() + if not new_session then + vim.notify('Failed to create new session', vim.log.levels.ERROR) + return + end + if not core.initialize_current_model():await() or not state.current_model then + vim.notify('No model selected', vim.log.levels.ERROR) + return + end + local providerId, modelId = state.current_model:match('^(.-)/(.+)$') + if not providerId or not modelId then + vim.notify('Invalid model format: ' .. tostring(state.current_model), vim.log.levels.ERROR) + return + end + state.active_session = new_session + M.open_input():await() + state.api_client + :send_command(state.active_session.id, { + command = 'review', + arguments = table.concat(args or {}, ' '), + model = state.current_model, + }) + :and_then(function() + vim.schedule(function() + require('opencode.history').write('/review ' .. table.concat(args or {}, ' ')) + end) + end) +end) + ---@type table M.commands = { open = { @@ -1008,6 +1041,14 @@ M.commands = { fn = M.swap_position, }, + review = { + desc = 'Review changes [commit|branch|pr], defaults to uncommitted changes', + fn = function(args) + M.review(args) + end, + nargs = '+', + }, + session = { desc = 'Manage sessions (new/select/child/compact/share/unshare/rename)', completions = { 'new', 'select', 'child', 'compact', 'share', 'unshare', 'agents_init', 'rename' }, @@ -1304,6 +1345,11 @@ M.slash_commands_map = { ['/rename'] = { fn = M.rename_session, desc = 'Rename current session' }, ['/thinking'] = { fn = M.toggle_reasoning_output, desc = 'Toggle reasoning output' }, ['/reasoning'] = { fn = M.toggle_reasoning_output, desc = 'Toggle reasoning output' }, + ['/review'] = { + fn = M.review, + desc = 'Review changes [commit|branch|pr], defaults to uncommitted changes', + args = true, + }, } M.legacy_command_map = { @@ -1442,6 +1488,7 @@ M.get_slash_commands = Promise.async(function() slash_cmd = slash_cmd, desc = def.desc, fn = def.fn, + args = def.args or false, }) end