1- local dispatch = require (' opencode.commands.dispatch ' )
1+ local commands = require (' opencode.commands' )
22local window = require (' opencode.commands.handlers.window' ).actions
33local session = require (' opencode.commands.handlers.session' ).actions
44local diff = require (' opencode.commands.handlers.diff' ).actions
@@ -7,119 +7,142 @@ local workflow = require('opencode.commands.handlers.workflow').actions
77local permission = require (' opencode.commands.handlers.permission' ).actions
88local agent = require (' opencode.commands.handlers.agent' ).actions
99
10- -- Routes an action through the dispatch pipeline so lifecycle hooks fire.
11- -- TODO: hooks (on_command_before/after/error/finally) are not yet in config
12- -- defaults — activate them when the event unification work lands.
13- local function via_dispatch (action_fn , ...)
14- local args = { ... }
15- return dispatch .dispatch_intent ({
16- ok = true ,
17- intent = { execute = function () return action_fn (unpack (args )) end , args = {}, range = nil },
18- }).result
10+ -- Route API actions through the same command execution axis.
11+ --- @param hook_key ? string
12+ local function dispatch_action (name , action_fn , hook_key , ...)
13+ local parsed = commands .build_parsed_intent (name , vim .deepcopy ({ ... }))
14+ if hook_key and parsed and parsed .ok and parsed .intent then
15+ parsed .intent .hook_key = hook_key
16+ end
17+
18+ return commands .execute_parsed_intent (parsed , function (resolved_args )
19+ return action_fn (unpack (resolved_args or {}))
20+ end )
1921end
2022
2123--- @type OpencodeCommandApi
2224local M = {}
2325
24- -- All dispatch-wrapped actions. Generated into M via the loop below.
25- -- Read-only queries (get_window_state, with_header, current_model) are defined after.
26- -- stylua: ignore
27- local actions = {
28- -- window
29- swap_position = window .swap_position ,
30- toggle_zoom = window .toggle_zoom ,
31- toggle_input = window .toggle_input ,
32- open_input = window .open_input ,
33- open_output = window .open_output ,
34- close = window .close ,
35- hide = window .hide ,
36- toggle_pane = window .toggle_pane ,
37- focus_input = window .focus_input ,
38- cancel = window .cancel ,
39- toggle_focus = window .toggle_focus , -- (new_sess)
40- toggle = window .toggle , -- (new_sess)
41- -- session
42- open_input_new_session = session .open_input_new_session ,
43- select_child_session = session .select_child_session ,
44- share = session .share ,
45- unshare = session .unshare ,
46- initialize = session .initialize ,
47- timeline = session .timeline ,
48- redo = session .redo ,
49- select_session = session .select_session , -- (parent_id)
50- compact_session = session .compact_session , -- (s)
51- open_input_new_session_with_title = session .open_input_new_session_with_title , -- (title)
52- rename_session = session .rename_session , -- (s, title)
53- undo = session .undo , -- (msg_id)
54- fork_session = session .fork_session , -- (msg_id)
55- -- diff
56- diff_next = diff .diff_next ,
57- diff_prev = diff .diff_prev ,
58- diff_close = diff .diff_close ,
59- diff_revert_all_last_prompt = diff .diff_revert_all_last_prompt ,
60- diff_revert_this_last_prompt = diff .diff_revert_this_last_prompt ,
61- set_review_breakpoint = diff .set_review_breakpoint ,
62- diff_open = diff .diff_open , -- (from, to)
63- diff_revert_all = diff .diff_revert_all , -- (snap)
64- diff_revert_selected_file = diff .diff_revert_selected_file , -- (s, t)
65- diff_restore_snapshot_file = diff .diff_restore_snapshot_file , -- (id)
66- diff_restore_snapshot_all = diff .diff_restore_snapshot_all , -- (id)
67- diff_revert_this = diff .diff_revert_this , -- (snap)
68- -- workflow
69- paste_image = workflow .paste_image ,
70- select_history = workflow .select_history ,
71- prev_history = workflow .prev_history ,
72- next_history = workflow .next_history ,
73- prev_prompt_history = workflow .prev_prompt_history ,
74- next_prompt_history = workflow .next_prompt_history ,
75- next_message = workflow .next_message ,
76- prev_message = workflow .prev_message ,
77- mention_file = workflow .mention_file ,
78- mention = workflow .mention ,
79- context_items = workflow .context_items ,
80- slash_commands = workflow .slash_commands ,
81- references = workflow .references ,
82- debug_output = workflow .debug_output ,
83- debug_message = workflow .debug_message ,
84- debug_session = workflow .debug_session ,
85- toggle_tool_output = workflow .toggle_tool_output ,
86- toggle_reasoning_output = workflow .toggle_reasoning_output ,
87- submit_input_prompt = workflow .submit_input_prompt ,
88- run = workflow .run , -- (prompt, opts)
89- run_new_session = workflow .run_new_session , -- (prompt, opts)
90- quick_chat = workflow .quick_chat , -- (msg, range)
91- run_user_command = workflow .run_user_command , -- (name, args)
92- review = workflow .review , -- (args, range)
93- add_visual_selection = workflow .add_visual_selection , -- (opts, range)
94- add_visual_selection_inline = workflow .add_visual_selection_inline , -- (o, r)
95- -- surface
96- help = surface .help ,
97- mcp = surface .mcp ,
98- commands_list = surface .commands_list ,
99- -- permission
100- question_answer = permission .question_answer ,
101- question_other = permission .question_other ,
102- respond_to_permission = permission .respond_to_permission , -- (answer, perm)
103- permission_accept = permission .permission_accept , -- (perm)
104- permission_accept_all = permission .permission_accept_all , -- (perm)
105- permission_deny = permission .permission_deny , -- (perm)
106- -- agent
107- configure_provider = agent .configure_provider ,
108- configure_variant = agent .configure_variant ,
109- cycle_variant = agent .cycle_variant ,
110- agent_plan = agent .agent_plan ,
111- agent_build = agent .agent_build ,
112- select_agent = agent .select_agent ,
113- switch_mode = agent .switch_mode ,
26+ local action_groups = {
27+ window = {
28+ swap_position = window .swap_position ,
29+ toggle_zoom = window .toggle_zoom ,
30+ toggle_input = window .toggle_input ,
31+ open_input = window .open_input ,
32+ open_output = window .open_output ,
33+ close = window .close ,
34+ hide = window .hide ,
35+ toggle_pane = window .toggle_pane ,
36+ focus_input = window .focus_input ,
37+ cancel = window .cancel ,
38+ toggle_focus = window .toggle_focus ,
39+ toggle = window .toggle ,
40+ },
41+
42+ session = {
43+ open_input_new_session = session .open_input_new_session ,
44+ select_child_session = session .select_child_session ,
45+ share = session .share ,
46+ unshare = session .unshare ,
47+ initialize = session .initialize ,
48+ timeline = session .timeline ,
49+ redo = session .redo ,
50+ select_session = session .select_session ,
51+ compact_session = session .compact_session ,
52+ open_input_new_session_with_title = session .open_input_new_session_with_title ,
53+ rename_session = session .rename_session ,
54+ undo = session .undo ,
55+ fork_session = session .fork_session ,
56+ },
57+
58+ diff = {
59+ diff_next = diff .diff_next ,
60+ diff_prev = diff .diff_prev ,
61+ diff_close = diff .diff_close ,
62+ diff_revert_all_last_prompt = diff .diff_revert_all_last_prompt ,
63+ diff_revert_this_last_prompt = diff .diff_revert_this_last_prompt ,
64+ set_review_breakpoint = diff .set_review_breakpoint ,
65+ diff_open = diff .diff_open ,
66+ diff_revert_all = diff .diff_revert_all ,
67+ diff_revert_selected_file = diff .diff_revert_selected_file ,
68+ diff_restore_snapshot_file = diff .diff_restore_snapshot_file ,
69+ diff_restore_snapshot_all = diff .diff_restore_snapshot_all ,
70+ diff_revert_this = diff .diff_revert_this ,
71+ },
72+
73+ workflow = {
74+ paste_image = workflow .paste_image ,
75+ select_history = workflow .select_history ,
76+ prev_history = workflow .prev_history ,
77+ next_history = workflow .next_history ,
78+ prev_prompt_history = workflow .prev_prompt_history ,
79+ next_prompt_history = workflow .next_prompt_history ,
80+ next_message = workflow .next_message ,
81+ prev_message = workflow .prev_message ,
82+ mention_file = workflow .mention_file ,
83+ mention = workflow .mention ,
84+ context_items = workflow .context_items ,
85+ slash_commands = workflow .slash_commands ,
86+ references = workflow .references ,
87+ debug_output = workflow .debug_output ,
88+ debug_message = workflow .debug_message ,
89+ debug_session = workflow .debug_session ,
90+ toggle_tool_output = workflow .toggle_tool_output ,
91+ toggle_reasoning_output = workflow .toggle_reasoning_output ,
92+ submit_input_prompt = workflow .submit_input_prompt ,
93+ run = workflow .run ,
94+ run_new_session = workflow .run_new_session ,
95+ quick_chat = workflow .quick_chat ,
96+ run_user_command = workflow .run_user_command ,
97+ review = workflow .review ,
98+ add_visual_selection = workflow .add_visual_selection ,
99+ add_visual_selection_inline = workflow .add_visual_selection_inline ,
100+ },
101+
102+ surface = {
103+ help = surface .help ,
104+ mcp = surface .mcp ,
105+ commands_list = surface .commands_list ,
106+ },
107+
108+ permission = {
109+ question_answer = permission .question_answer ,
110+ question_other = permission .question_other ,
111+ respond_to_permission = permission .respond_to_permission ,
112+ permission_accept = permission .permission_accept ,
113+ permission_accept_all = permission .permission_accept_all ,
114+ permission_deny = permission .permission_deny ,
115+ },
116+
117+ agent = {
118+ configure_provider = agent .configure_provider ,
119+ configure_variant = agent .configure_variant ,
120+ cycle_variant = agent .cycle_variant ,
121+ agent_plan = agent .agent_plan ,
122+ agent_build = agent .agent_build ,
123+ select_agent = agent .select_agent ,
124+ switch_mode = agent .switch_mode ,
125+ },
126+
127+ query = {
128+ get_window_state = window .get_window_state ,
129+ current_model = agent .current_model ,
130+ with_header = surface .with_header ,
131+ },
114132}
115133
116- for name , fn in pairs (actions ) do
117- M [name ] = function (...) return via_dispatch (fn , ... ) end
134+ --- @param group_name string
135+ --- @param exports table<string , function>
136+ local function register_exports (group_name , exports )
137+ for name , fn in pairs (exports ) do
138+ M [name ] = function (...)
139+ return dispatch_action (name , fn , group_name , ... )
140+ end
141+ end
118142end
119143
120- -- Read-only queries: bypass dispatch, no side effects
121- function M .get_window_state () return window .get_window_state () end
122- function M .current_model () return agent .current_model () end
123- function M .with_header (lines , show_welcome ) return surface .with_header (lines , show_welcome ) end
144+ for group_name , exports in pairs (action_groups ) do
145+ register_exports (group_name , exports )
146+ end
124147
125148return M
0 commit comments