Skip to content

feat(tmux): add fallback server discovery for split panes#150

Open
e-cal wants to merge 5 commits intonickjvandyke:mainfrom
e-cal:feature/tmux-pane-discovery
Open

feat(tmux): add fallback server discovery for split panes#150
e-cal wants to merge 5 commits intonickjvandyke:mainfrom
e-cal:feature/tmux-pane-discovery

Conversation

@e-cal
Copy link
Contributor

@e-cal e-cal commented Jan 28, 2026

Adds fallback discovery logic for opencode sessions active in a tmux sibling pane but not matching CWD.

For tmux users, it is reasonable to assume that if they have a split open with opencode and fire off a prompt from nvim, they likely intend it to go to that instance in the split whether it matches the CWD discovery logic or not. Overall, makes it much more intuitive where your prompt will end up, and avoids unnecessarily launching new sessions.

Implemented as a fallback, so if there is a different session that does get discovered we still connect to that as normal. When there are multiple splits running opencode and none share CWD, it just picks the first one it finds. And then if there are no opencode instances in splits, use the normal logic of launching and connecting via the plugin.

Currently only affects tmux users, but implemented such that any provider can implement a find_server function to attempt another discovery before failing.


Also adds auto_close option to the tmux provider. When set to false, the tmux pane will not auto-close when opencode exits. Defaults to true to maintain current behavior out of the box.

vim.g.opencode_opts = {
  provider = {
    tmux = {
      auto_close = false, -- Keep the tmux pane open after opencode exits
    }
  }
}

Relation to #119

This is complementary to #119 but solves a different problem:

  • fix(tmux): use pane PID to find correct opencode server port #119: Fixes selecting the wrong opencode when multiple instances share the same CWD. Works by tracking the pane the provider created via self.pane_id.
  • This PR: Fixes discovery when opencode was started before nvim and/or CWD doesn't match. Since the provider didn't create the pane, self.pane_id is nil and get_port() returns nil.

This PR searches all sibling panes in the current tmux window via TTY, regardless of whether the provider started them.

Changes

  • lua/opencode/cli/server.lua: Use provider's find_server() as fallback when CWD matching fails
  • lua/opencode/provider/tmux.lua: Add find_server() method that discovers opencode in sibling tmux panes, add auto_close config option
  • lua/opencode/provider/init.lua: Document the new find_server field in the Provider interface
  • lua/opencode/config.lua: Add auto_close default config for tmux provider

Copilot AI review requested due to automatic review settings January 28, 2026 18:27
@e-cal e-cal changed the title feat(tmux): add fallback opencode server discovery for split panes feat(tmux): add fallback server discovery for split panes Jan 28, 2026
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends server discovery so that, when CWD-based matching fails, providers can perform their own search for existing opencode instances, with an initial implementation for tmux that inspects sibling panes. The goal is to make it much more intuitive for tmux users where prompts are sent, especially when an opencode pane was started before Neovim or with a different CWD.

Changes:

  • Add a provider-specific find_server hook and wire it into opencode.cli.server as a fallback when CWD-based discovery finds no server.
  • Implement Tmux:find_server() to scan sibling tmux panes by TTY, detect opencode processes, and derive the listening port and cwd via lsof and the /path endpoint.
  • Document the new find_server capability in the provider interface so other providers can add their own discovery strategies.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
lua/opencode/cli/server.lua Extends find_server_inside_nvim_cwd() to call provider:find_server() as a fallback before giving up and starting a new server.
lua/opencode/provider/tmux.lua Adds Tmux:find_server() that discovers opencode processes in sibling panes by TTY, extracts their listening port, and returns a populated Server descriptor.
lua/opencode/provider/init.lua Updates the opencode.Provider type docs to include an optional find_server method used for provider-specific fallback discovery.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@nickjvandyke nickjvandyke force-pushed the main branch 6 times, most recently from de5f1cc to 5de2380 Compare February 2, 2026 16:31
@e-cal
Copy link
Contributor Author

e-cal commented Feb 3, 2026

@nickjvandyke this is ready now. let me know if you have any questions, but should be a big QoL improvement for us tmux users (or at least it is for myself)

@nickjvandyke
Copy link
Owner

nickjvandyke commented Feb 3, 2026

@e-cal I'm working on a server-selection feature as a more general solution to this issue. What would you think about that?

i.e. when sending to opencode:

  1. If only one exists in the CWD, select it
  2. If multiple exist in the CWD, prompt user to select one (and cache it)
  3. If none exist in the CWD, prompt user to select from all (and cache it). I didn't have this planned, but could add it based on this PR/issue.

Plus the ability to select a server at any time of course 😀

Separately we'd have to think about how to format filepaths when opencode doesn't share the same CWD.

@e-cal
Copy link
Contributor Author

e-cal commented Feb 4, 2026

ah that would be great! I think i would still want that extra layer of tmux split fallback in the middle though.

If the server select is hackable in the sense I can give it a custom sorter (like telescope) and make it auto select instead of prompting me I think this is perfect.

My most common use case is having opencode in a tmux split with cwd in some parent dir (e.g. ~/projects), then nvim in a specific project in another split. In these unambiguous cases it would be nice to still have frictionless connection.

But with that being said I’d be happy to build on top of the server discovery, with non-default config options so it doesn’t break things for others. Or just set this up in my own config.

@nickjvandyke
Copy link
Owner

nickjvandyke commented Feb 4, 2026

I might be open to auto-selecting the single opencode server even when it's in another CWD. That would address your use case right? I worry that could confuse users but I'm probably underestimating them 😂

@e-cal
Copy link
Contributor Author

e-cal commented Feb 4, 2026

Unfortunately not, I almost always have multiple opencode servers running at a given time.

I would be happy to add another provider.tmux config option to make this not default behavior to avoid confusing users. Or, alternatively, make the provider discovery logic extensible so I can add it to just my config (but I suspect other tmux users would also find this to be a nice feature).

But the discovery logic I'm looking for is:

  1. configured port
  2. cwd match
  3. tmux sibling pane (this pr, can add a config option to disable by default)
  4. spawn new session

Or, with the server discovery you're working on:

  1. configured port
  2. cwd match
  3. tmux sibling pane (off by default?)
  4. interactive selection
  5. spawn new session

I rely heavily on (3).

To avoid confusion I would suggest just another two config options: e.g. auto_match or the inverse like manual_server_selection (or whatever you want to call them) and provider.tmux.match_sibling_pane.

Set them both false by default so out-of-the-box you get the selection prompt, but people like myself can get the connection with 0 friction.

I think by keeping all defaults to current or interactive behavior is a really good idea to keep things intuitive for the majority of users, but I would like to be able to override it.

@nickjvandyke
Copy link
Owner

Thanks for ideating!

I want to generalize this solution as much as possible - I can't keep up with everyone's specific needs 😅

For 3, I think it makes sense to expose a configurable server discovery. Either in providers (like you did here), or completely separate.

I'll try to get back to you on that as this new feature settles!

(sorry for the merge conflicts!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants