Skip to content

TUI: add Unix socket for external filter control #482

@wesm

Description

@wesm

Summary

Add a Unix domain socket listener to roborev tui so that external applications can programmatically control the TUI's repo/branch filter. This enables integration with terminal multiplexers and workspace managers that want to keep the roborev TUI's filter state in sync with the user's current working context.

Motivation

When using roborev TUI alongside a tool that manages multiple worktrees, switching between worktrees requires manually changing the filter in the TUI (f key → select repo → select branch). An external control mechanism would allow the surrounding tool to send a filter command automatically when the user switches context, keeping the review list relevant without manual intervention.

Proposed Design

Socket location

On startup, the TUI opens a Unix domain socket at a discoverable path:

  • $XDG_RUNTIME_DIR/roborev/tui.sock, or
  • ~/.local/state/roborev/tui.sock as fallback

The socket path is also written to a PID-indexed file (e.g., ~/.local/state/roborev/tui-<pid>.sock) for cases where multiple TUI instances run concurrently.

Protocol

Newline-delimited JSON over the Unix socket:

// Set filter (repo and/or branch)
→ {"cmd": "set-filter", "repo": "/path/to/repo", "branch": "feat-x"}
← {"ok": true}

// Set repo filter only, clear branch
→ {"cmd": "set-filter", "repo": "/path/to/repo", "branch": ""}
← {"ok": true}

// Clear all filters
→ {"cmd": "clear-filter"}
← {"ok": true}

// Query current filter state
→ {"cmd": "get-filter"}
← {"ok": true, "repo": "/path/to/repo", "branch": "feat-x"}

Implementation

  1. Add a goroutine in the TUI that accepts connections on the Unix socket
  2. Parse incoming JSON commands
  3. Convert to a Bubbletea message (e.g., setFilterMsg{repo, branch}) and send via Program.Send()
  4. The Update() handler processes setFilterMsg the same way as a user selecting a filter in the modal — sets activeRepoFilter and activeBranchFilter, increments fetchSeq, and calls fetchJobs()
  5. Respect existing filter lock semantics: if a filter was locked via --repo or --branch CLI flags, the socket command should not override it (return an error response)
  6. Clean up the socket file on TUI exit

Considerations

  • The socket listener should be opt-in (e.g., --control-socket flag or config key) to avoid creating files unexpectedly
  • Multiple TUI instances should be supported (PID-indexed socket paths)
  • Socket permissions should be user-only (0600)
  • The listener goroutine must not block the Bubbletea event loop

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions