@@ -28,6 +28,8 @@ local store = require('opencode.state.store')
2828--- @field messages OpencodeMessage[] | nil
2929--- @field current_message OpencodeMessage | nil
3030--- @field pending_permissions OpencodePermission[]
31+ --- @field pending_prompt_permissions OpencodePermission[]
32+ --- @field pending_questions OpencodeQuestionRequest[]
3133--- @field cost number
3234--- @field tokens_count number
3335--- @field user_message_count table<string , number>
@@ -141,6 +143,8 @@ local function default_runtime(id)
141143 messages = nil ,
142144 current_message = nil ,
143145 pending_permissions = {},
146+ pending_prompt_permissions = {},
147+ pending_questions = {},
144148 cost = 0 ,
145149 tokens_count = 0 ,
146150 user_message_count = {},
@@ -215,6 +219,139 @@ function M.get(id)
215219 return runtimes [id ]
216220end
217221
222+ --- @param session_id string | nil
223+ --- @return OpencodeSessionTabRuntime | nil
224+ function M .find_by_session_id (session_id )
225+ if not session_id or session_id == ' ' then
226+ return nil
227+ end
228+
229+ for _ , runtime in ipairs (M .list ()) do
230+ if runtime .active_session and runtime .active_session .id == session_id then
231+ return runtime
232+ end
233+
234+ local render_state = runtime .renderer_context and runtime .renderer_context .render_state
235+ if render_state and render_state .get_task_part_by_child_session then
236+ local ok , task_part = pcall (render_state .get_task_part_by_child_session , render_state , session_id )
237+ if ok and task_part then
238+ return runtime
239+ end
240+ end
241+ end
242+
243+ local current = M .current ()
244+ if current and current .active_session and current .active_session .id then
245+ local render_state = require (' opencode.ui.renderer.ctx' ).render_state
246+ if render_state :get_task_part_by_child_session (session_id ) then
247+ return current
248+ end
249+ end
250+ end
251+
252+ --- @param tab_id string
253+ --- @param permission OpencodePermission
254+ function M .add_pending_permission (tab_id , permission )
255+ local runtime = runtimes [tab_id ]
256+ if not runtime or not permission or not permission .id then
257+ return
258+ end
259+
260+ for index , existing in ipairs (runtime .pending_prompt_permissions ) do
261+ if existing .id == permission .id then
262+ runtime .pending_prompt_permissions [index ] = permission
263+ notify_change ()
264+ return
265+ end
266+ end
267+
268+ table.insert (runtime .pending_prompt_permissions , permission )
269+ notify_change ()
270+ end
271+
272+ --- @param tab_id string
273+ --- @param permission_id string
274+ function M .remove_pending_permission (tab_id , permission_id )
275+ local runtime = runtimes [tab_id ]
276+ if not runtime or not permission_id then
277+ return
278+ end
279+
280+ for index , permission in ipairs (runtime .pending_prompt_permissions ) do
281+ if permission .id == permission_id then
282+ table.remove (runtime .pending_prompt_permissions , index )
283+ notify_change ()
284+ return
285+ end
286+ end
287+ end
288+
289+ --- @param tab_id string
290+ --- @param question OpencodeQuestionRequest
291+ function M .add_pending_question (tab_id , question )
292+ local runtime = runtimes [tab_id ]
293+ if not runtime or not question or not question .id then
294+ return
295+ end
296+
297+ for index , existing in ipairs (runtime .pending_questions ) do
298+ if existing .id == question .id then
299+ runtime .pending_questions [index ] = question
300+ notify_change ()
301+ return
302+ end
303+ end
304+
305+ table.insert (runtime .pending_questions , question )
306+ notify_change ()
307+ end
308+
309+ --- @param tab_id string
310+ --- @param question_id string
311+ function M .remove_pending_question (tab_id , question_id )
312+ local runtime = runtimes [tab_id ]
313+ if not runtime or not question_id then
314+ return
315+ end
316+
317+ for index , question in ipairs (runtime .pending_questions ) do
318+ if question .id == question_id then
319+ table.remove (runtime .pending_questions , index )
320+ notify_change ()
321+ return
322+ end
323+ end
324+ end
325+
326+ --- @param tab_id string
327+ function M .clear_pending_prompts (tab_id )
328+ local runtime = runtimes [tab_id ]
329+ if not runtime then
330+ return
331+ end
332+
333+ local active = M .active_id () == tab_id
334+ local has_pending = # runtime .pending_permissions > 0
335+ or # runtime .pending_prompt_permissions > 0
336+ or # runtime .pending_questions > 0
337+ if active then
338+ has_pending = has_pending or # (store .get (' pending_permissions' ) or {}) > 0
339+ end
340+ if not has_pending then
341+ return
342+ end
343+
344+ runtime .pending_permissions = {}
345+ runtime .pending_prompt_permissions = {}
346+ runtime .pending_questions = {}
347+ if active then
348+ store .batch (function ()
349+ store .set (' pending_permissions' , {})
350+ end )
351+ end
352+ notify_change ()
353+ end
354+
218355--- @return OpencodeSessionTabRuntime | nil
219356function M .current ()
220357 local runtime = runtimes [store .get (' active_session_tab' )]
@@ -337,6 +474,8 @@ function M.create(session)
337474 runtime .messages = nil
338475 runtime .current_message = nil
339476 runtime .pending_permissions = {}
477+ runtime .pending_prompt_permissions = {}
478+ runtime .pending_questions = {}
340479 runtime .restore_points = {}
341480 runtime .last_sent_context = nil
342481 runtime .user_message_count = {}
0 commit comments