@@ -94,7 +94,7 @@ describe('opencode.commands.handlers', function()
9494 assert .same ({ ' accept' , ' accept_all' , ' deny' }, defs .permission .completions )
9595 assert .same ({ allow_empty = false }, defs .permission .nested_subcommand )
9696
97- assert .same ({ ' new' , ' select' , ' child' , ' compact' , ' share' , ' unshare' , ' agents_init' , ' rename' }, defs .session .completions )
97+ assert .same ({ ' new' , ' select' , ' child' , ' sibling ' , ' parent ' , ' compact' , ' share' , ' unshare' , ' agents_init' , ' rename' }, defs .session .completions )
9898 assert .same ({ allow_empty = false }, defs .session .nested_subcommand )
9999
100100 assert .same ({ ' input' , ' output' }, defs .open .completions )
@@ -203,4 +203,150 @@ describe('opencode.commands.handlers', function()
203203 assert .equal (' all' , called .scope )
204204 assert .is_nil (called .snapshot_id )
205205 end )
206+
207+ it (' select_sibling_session calls select_session with parentID when active session is a child' , function ()
208+ local session_handler = require (' opencode.commands.handlers.session' )
209+ local session_runtime = require (' opencode.services.session_runtime' )
210+ local state = require (' opencode.state' )
211+
212+ state .session .set_active ({ id = ' child1' , parentID = ' root1' , title = ' Child 1' })
213+ local called_parent_id
214+ local original = session_runtime .select_session
215+ session_runtime .select_session = function (parent_id )
216+ called_parent_id = parent_id
217+ end
218+
219+ session_handler .actions .select_sibling_session ()
220+
221+ session_runtime .select_session = original
222+ assert .equal (' root1' , called_parent_id )
223+ end )
224+
225+ it (' select_sibling_session falls back to root sessions when active session has no parent' , function ()
226+ local session_handler = require (' opencode.commands.handlers.session' )
227+ local session_runtime = require (' opencode.services.session_runtime' )
228+ local state = require (' opencode.state' )
229+
230+ state .session .set_active ({ id = ' root1' , parentID = nil , title = ' Root' })
231+ local called_parent_id = ' sentinel'
232+ local original = session_runtime .select_session
233+ session_runtime .select_session = function (parent_id )
234+ called_parent_id = parent_id
235+ end
236+
237+ local notify_stub = stub (vim , ' notify' )
238+ session_handler .actions .select_sibling_session ()
239+ notify_stub :revert ()
240+
241+ session_runtime .select_session = original
242+ assert .is_nil (called_parent_id )
243+ end )
244+
245+ it (' select_parent_session switches to parent when active session is a child' , function ()
246+ local session_handler = require (' opencode.commands.handlers.session' )
247+ local session_runtime = require (' opencode.services.session_runtime' )
248+ local state = require (' opencode.state' )
249+
250+ state .session .set_active ({ id = ' child1' , parentID = ' root1' , title = ' Child 1' })
251+ local switched_to
252+ local original = session_runtime .switch_session
253+ session_runtime .switch_session = function (session_id )
254+ switched_to = session_id
255+ end
256+
257+ session_handler .actions .select_parent_session ()
258+
259+ session_runtime .switch_session = original
260+ assert .equal (' root1' , switched_to )
261+ end )
262+
263+ it (' select_parent_session notifies when active session has no parent' , function ()
264+ local session_handler = require (' opencode.commands.handlers.session' )
265+ local session_runtime = require (' opencode.services.session_runtime' )
266+ local state = require (' opencode.state' )
267+
268+ state .session .set_active ({ id = ' root1' , parentID = nil , title = ' Root' })
269+ local switched_to = nil
270+ local original = session_runtime .switch_session
271+ session_runtime .switch_session = function (session_id )
272+ switched_to = session_id
273+ end
274+
275+ local notify_stub = stub (vim , ' notify' )
276+ session_handler .actions .select_parent_session ()
277+
278+ session_runtime .switch_session = original
279+ assert .is_nil (switched_to )
280+ assert .stub (notify_stub ).was_called ()
281+ notify_stub :revert ()
282+ end )
283+
284+ it (' select_sibling_session does nothing when no active session' , function ()
285+ local session_handler = require (' opencode.commands.handlers.session' )
286+ local session_runtime = require (' opencode.services.session_runtime' )
287+ local state = require (' opencode.state' )
288+
289+ state .session .set_active (nil )
290+ local called = false
291+ local original = session_runtime .select_session
292+ session_runtime .select_session = function ()
293+ called = true
294+ end
295+
296+ local notify_stub = stub (vim , ' notify' )
297+ session_handler .actions .select_sibling_session ()
298+ notify_stub :revert ()
299+
300+ session_runtime .select_session = original
301+ assert .is_true (called )
302+ end )
303+
304+ it (' select_parent_session does nothing when no active session' , function ()
305+ local session_handler = require (' opencode.commands.handlers.session' )
306+ local session_runtime = require (' opencode.services.session_runtime' )
307+ local state = require (' opencode.state' )
308+
309+ state .session .set_active (nil )
310+ local switched_to = nil
311+ local original = session_runtime .switch_session
312+ session_runtime .switch_session = function (session_id )
313+ switched_to = session_id
314+ end
315+
316+ local notify_stub = stub (vim , ' notify' )
317+ session_handler .actions .select_parent_session ()
318+
319+ session_runtime .switch_session = original
320+ assert .is_nil (switched_to )
321+ assert .stub (notify_stub ).was_called ()
322+ notify_stub :revert ()
323+ end )
324+
325+ it (' session subcommand sibling routes to select_sibling_session' , function ()
326+ local session_handler = require (' opencode.commands.handlers.session' )
327+ local called = false
328+ local original = session_handler .actions .select_sibling_session
329+ session_handler .actions .select_sibling_session = function ()
330+ called = true
331+ end
332+
333+ session_handler .command_defs .session .execute ({ ' sibling' })
334+
335+ session_handler .actions .select_sibling_session = original
336+ assert .is_true (called )
337+ end )
338+
339+ it (' session subcommand parent routes to select_parent_session' , function ()
340+ local session_handler = require (' opencode.commands.handlers.session' )
341+ local called = false
342+ local original = session_handler .actions .select_parent_session
343+ session_handler .actions .select_parent_session = function ()
344+ called = true
345+ end
346+
347+ session_handler .command_defs .session .execute ({ ' parent' })
348+
349+ session_handler .actions .select_parent_session = original
350+ assert .is_true (called )
351+ end )
206352end )
0 commit comments