Skip to content

Design: Treat session tabs as containers, not session views #541

Closed

Description

@wzj-zz

Summary

PR #525 implements session tab persistence, but the current model conflates tabs and sessions. This issue proposes a design where tabs are containers and sessions are content, similar to Neovim's window/buffer relationship.

Design Proposal

Core principle: Persist the tab (container), not the session (content).

Neovim opencode.nvim Role
window session tab Container, persists independently
buffer agent session Content, can be created/deleted

Operation Semantics

Operation Container Effect Content Effect
<M-c> (new tab) New container created New session created and filled
<C-a> (select session) Container unchanged Swap to existing session
<C-n> (new session) Container unchanged Replace with new session

Key: <M-c> creates container + fills it so user can chat immediately. <C-a>/<C-n> only change what the container holds.

Bugs Found in Current Implementation

Bug 1: Tabs created before panel open are lost

  1. Open Neovim, do NOT open panel
  2. Press <M-c> 3 times, send messages
  3. :q, reopen — only 1 tab restored

Cause: M.save() iterates groups, but groups is empty unless M.restore() was called (panel opened).

Bug 2: Empty tabs not persisted

  1. Open panel, press <M-c>, do NOT send message
  2. :q, reopen — tab missing

Cause: save_group() skips tabs where active_session == nil.

Bug 3: <C-a> session switch not persisted

  1. Tab 2 shows Session A
  2. Press <C-a>, switch to Session B
  3. :q, reopen — Tab 2 shows Session A again

Cause: M.set_active() updates global store but not the tab's active_session field.

Proposed Behavior

Scenario Current Proposed
Empty tab after restart Lost Restored as empty container
Session deleted server-side Tab shows "N/A" Tab becomes empty container
<C-a> switch Ephemeral Persisted

Questions

  1. Agree with "tab as container, session as content" model?
  2. Should empty tabs be persistent?
  3. Should <C-a> switching be durable across restarts?
  4. Should <M-c> auto-fill with new session (so user can chat immediately)?
  5. Deleted session: show "N/A" or empty container?

Environment

  • OS: Windows 11
  • Neovim: 0.12.5
  • opencode.nvim: latest main (commit 494e474)
  • opencode executable: opencode2 (v2 protocol)

Related: PR #525, Issue #519

Activity

  1. wzj-zz commented on Oct 17, 2026

    @wzj-zz
    ContributorAuthor

    @sudo-tee Thanks for merging PR #525! The project-scoped tab groups work great. These are follow-up refinements I discovered during deeper testing, not criticisms of the original implementation. I appreciate your quick iterations on this feature.

  2. sudo-tee commented on Oct 20, 2026

    @sudo-tee
    Owner

    I think this MR can help with this workflow

    #543

    It will not persist tabs with a session and no prompt sent.

  3. sudo-tee commented on Oct 20, 2026

    @sudo-tee
    Owner

    For the container, you can already reuse a tab to see another session

    leader oI does that and the session picker also use the current tab. leader oN create a new tab (with a new session for the moment) but the PR I sent in my other message is fixing this . It will be a draft session

    Not sure what is missing

  4. wzj-zz commented on Oct 20, 2026

    @wzj-zz
    ContributorAuthor

    Thanks for clarifying the <leader>oI and session picker behaviors. However, I realize my use case with <C-a> is different from both:

    My <C-a> workflow:

    • I'm on Tab 1 showing Session A
    • I press <C-a> to open the session picker
    • I select existing Session B
    • Tab 1 directly switches to show Session B (no new tab, no jumping away)

    This differs from:

    • <leader>oI: Stays in current tab, but creates a new session
    • Session picker: Selects existing session, but jumps to its tab or creates new tab

    The bug I encountered:

    • After switching with <C-a>, Tab 1 correctly shows Session B
    • But after restarting Neovim, Tab 1 restores showing Session A, not Session B
    • The switch was not persisted

    Questions:

    1. Is this the intended behavior, or a bug?
    2. If I want to switch the current tab to an existing session (without creating a new tab), which operation should I use?

    For context, I have <C-a> mapped to select_session which calls session_runtime.select_session.

  5. sudo-tee commented on Oct 20, 2026

    @sudo-tee
    Owner
  6. sudo-tee commented on Oct 21, 2026

    @sudo-tee
    Owner

    @wzj-zz

    I am not able to reproduce the issue if I use the session picker on a tab it properly switch and is restored with the new session.

    Can you give it a try with latest changes or record a video if you are still able to reproduce ?

  7. wzj-zz commented on Oct 21, 2026

    @wzj-zz
    ContributorAuthor

    @sudo-tee Here is the video demonstrating the <C-a> session switch persistence issue.

    Video:

    issue541_compressed.mp4

    What the video shows:

    1. Open Neovim with existing session "Quick check-in" (Session A)
    2. Press <C-a>, select "Test message 222" (Session B)
    3. Tab now shows Session B
    4. Close Neovim
    5. Reopen — Tab restores showing Session A, not Session B

    Environment:

    • OS: Windows 11
    • Neovim: 0.12.5
    • opencode.nvim: latest main (97566da)
    • opencode executable: opencode2 (v2 protocol)

    The session switch works in the current instance, but is not persisted across restarts.

  8. added 3 commits that reference this issue on Oct 21, 2026
    9388647
    2478990
    665d1b9
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions