Tmux Multiplexer Support
Relevant source files
The following files were used as context for generating this wiki page:
- buddi/Buddi/Services/Tmux/TmuxController.swift
- buddi/Buddi/Services/Tmux/TmuxPathFinder.swift
- buddi/Buddi/Services/Tmux/TmuxSessionMatcher.swift
- buddi/Buddi/Services/Tmux/TmuxTargetFinder.swift
- buddi/Buddi/Services/Tmux/ToolApprovalHandler.swift
- buddi/Buddi/Models/TmuxTarget.swift
- buddi/Buddi/Services/Shared/ProcessTreeBuilder.swift
The Tmux Multiplexer Support system in Buddi provides the infrastructure necessary to monitor, target, and interact with Claude Code sessions running inside terminal multiplexers. It specifically supports standard tmux and the specialized cmux multiplexer. This support enables the Buddi app to perform complex operations like automated tool approval, session matching via screen scraping, and window focusing by mapping process IDs (PIDs) to specific multiplexer panes or surfaces.
Sources: README.md:14, buddi/Buddi/Services/Tmux/TmuxTargetFinder.swift:13-25
Architecture and Core Components
The system is built as a set of specialized actors and services that handle different aspects of multiplexer interaction. The architecture relies on the ProcessTreeBuilder to understand the relationship between the host system, the multiplexer processes, and the Claude Code instances.
Multi-Multiplexer Abstraction
Buddi treats both tmux and cmux through a unified TmuxTarget model. This allows higher-level services to interact with "targets" without needing to know the specific underlying multiplexer implementation details for every call.
| Component | Description |
|---|---|
TmuxController | High-level actor acting as the primary entry point for multiplexer operations. |
TmuxTargetFinder | Logic for locating which pane or surface a specific Claude PID is running in. |
ToolApprovalHandler | Handles sending keystrokes (e.g., "1" for approve, "n" for reject) to targets. |
TmuxSessionMatcher | Matches terminal panes to Claude JSONL session files by sampling visible text. |
TmuxPathFinder | Locates and caches executable paths for tmux and cmux. |
Sources: buddi/Buddi/Models/TmuxTarget.swift:10-25, buddi/Buddi/Services/Tmux/TmuxController.swift:12-16, buddi/Buddi/Services/Tmux/TmuxPathFinder.swift:11-15
Data Flow for Target Resolution
The following diagram illustrates how Buddi resolves a Claude PID to a specific multiplexer target.
Target Identification and Matching
Finding the correct terminal pane is complex because PIDs are often nested deep within the shell process tree.
PID-Based Discovery
For tmux, the system runs list-panes with the #{pane_pid} format to get the base shell PID of every pane. It then uses the ProcessTreeBuilder to check if the Claude PID is a descendant of that pane's PID.
For cmux, the system enumerates all workspaces and surfaces. Since direct PID mapping is less straightforward in cmux, it utilizes a combination of working directory (CWD) matching, window titles, and screen content sampling.
Sources: buddi/Buddi/Services/Tmux/TmuxTargetFinder.swift:51-70, buddi/Buddi/Services/Tmux/TmuxTargetFinder.swift:122-160
Screen Sampling (Session Matcher)
The TmuxSessionMatcher provides high-confidence matching by "scraping" the content of a pane and comparing it to local Claude session files (.jsonl).
- Capture: Uses
capture-pane(tmux) orread-screen(cmux) to get the last 500 lines. - Snippet Extraction: Identifies unique text strings (at least 25 characters, excluding common code symbols or comments).
- Scoring: Checks potential session files for these snippets. A match of 2 or more snippets confirms the session ID.
Sources: buddi/Buddi/Services/Tmux/TmuxSessionMatcher.swift:23-55, buddi/Buddi/Services/Tmux/TmuxSessionMatcher.swift:102-127
Tool Approval and Interaction
The ToolApprovalHandler allows Buddi to respond to Claude Code's permission requests by sending literal keystrokes to the terminal.
Tmux Interaction
Interaction with standard tmux is performed via the send-keys command. Text is sent with the -l flag to ensure it is interpreted literally.
// Example of sending '1' + Enter for approval
let textArgs = ["send-keys", "-t", targetStr, "-l", "1"]
let enterArgs = ["send-keys", "-t", targetStr, "Enter"]
Sources: buddi/Buddi/Services/Tmux/ToolApprovalHandler.swift:65-80
Cmux Interaction and Security
Interacting with cmux requires a control password, typically read from ~/Library/Application Support/cmux/socket-control-password. Additionally, the user must set cmux to "Automation mode" in its settings to allow external socket access.
| Action | tmux Command | cmux Command |
|---|---|---|
| Focus | select-pane -t [target] | tab-action --action select --surface [ref] |
| Send Text | send-keys -t [target] -l [keys] | send --surface [ref] [keys] |
| Send Enter | send-keys -t [target] Enter | send-key --surface [ref] return |
Sources: buddi/Buddi/Services/Tmux/ToolApprovalHandler.swift:93-125, buddi/Buddi/Services/Tmux/TmuxController.swift:58-91
Path Management
The TmuxPathFinder handles the discovery of executables across different macOS architectures (Apple Silicon vs. Intel). It checks common Homebrew paths and system paths, caching the result to avoid repeated disk I/O.
Summary
The Tmux Multiplexer Support system serves as a bridge between the Buddi macOS UI and terminal-bound Claude sessions. By abstracting the differences between tmux and cmux, and implementing deep process-tree inspection and screen content matching, the system ensures that Buddi can reliably automate tool approvals and session tracking regardless of how the user manages their terminal windows.