Skip to content

Commit a98539e

Browse files
feat: add prompt_guard callback mechanism
- Add prompt_guard configuration option (function that returns boolean) - Check guard before sending prompts (ERROR notification if denied) - Check guard before opening buffer first time (WARN notification if denied) - Add util.check_prompt_allowed() helper functions - Guard has no parameters, users can access vim state directly - Proper error handling for guard callback failures
1 parent bebe01c commit a98539e

File tree

4 files changed

+44
-0
lines changed

4 files changed

+44
-0
lines changed

lua/opencode/config.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ M.defaults = {
167167
enabled = false,
168168
capture_streamed_events = false,
169169
},
170+
prompt_guard = nil,
170171
}
171172

172173
M.values = vim.deepcopy(M.defaults)

lua/opencode/core.lua

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@ function M.open(opts)
4848
local are_windows_closed = state.windows == nil
4949

5050
if are_windows_closed then
51+
-- Check if opening buffer is allowed
52+
local allowed, err_msg = util.check_prompt_allowed(config.prompt_guard)
53+
54+
if not allowed then
55+
vim.notify(err_msg or 'Opening opencode buffer denied by prompt_guard', vim.log.levels.WARN)
56+
return
57+
end
58+
5159
state.windows = ui.create_windows()
5260
end
5361

@@ -81,6 +89,14 @@ end
8189
--- @param prompt string The message prompt to send.
8290
--- @param opts? SendMessageOpts
8391
function M.send_message(prompt, opts)
92+
-- Check if prompt is allowed
93+
local allowed, err_msg = util.check_prompt_allowed(config.prompt_guard)
94+
95+
if not allowed then
96+
vim.notify(err_msg or 'Prompt denied by prompt_guard', vim.log.levels.ERROR)
97+
return
98+
end
99+
84100
opts = opts or {}
85101
opts.context = opts.context or config.context
86102
opts.model = opts.model or state.current_model

lua/opencode/types.lua

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@
141141
---@field ui OpencodeUIConfig
142142
---@field context OpencodeContextConfig
143143
---@field debug OpencodeDebugConfig
144+
---@field prompt_guard? fun(): boolean
144145

145146
---@class MessagePartState
146147
---@field input TaskToolInput|BashToolInput|FileToolInput|TodoToolInput|GlobToolInput|GrepToolInput|WebFetchToolInput|ListToolInput Input data for the tool

lua/opencode/util.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,4 +360,30 @@ function M.parse_dot_args(args_str)
360360
return result
361361
end
362362

363+
--- Check if prompt is allowed via guard callback
364+
--- @param guard_callback? function
365+
--- @return boolean allowed
366+
--- @return string|nil error_message
367+
function M.check_prompt_allowed(guard_callback)
368+
if not guard_callback then
369+
return true, nil -- No guard = always allowed
370+
end
371+
372+
if not type(guard_callback) == 'function' then
373+
return false, 'prompt_guard must be a function'
374+
end
375+
376+
local success, result = pcall(guard_callback)
377+
378+
if not success then
379+
return false, 'prompt_guard error: ' .. tostring(result)
380+
end
381+
382+
if type(result) ~= 'boolean' then
383+
return false, 'prompt_guard must return a boolean'
384+
end
385+
386+
return result, nil
387+
end
388+
363389
return M

0 commit comments

Comments
 (0)