Skip to content

feat: Abstract tmux behind a Multiplexer interface #27

@nigel-dev

Description

@nigel-dev

Description

MC is tightly coupled to tmux — every session/window/pane operation directly calls the `tmux` binary. This prevents supporting alternative terminal multiplexers (Zellij, Wezterm) or lightweight PTY-based backends for simple tasks.

Current State

`src/lib/tmux.ts` contains 14+ functions that all directly call `tmux`:

  • `createSession`, `sessionExists`, `killSession`
  • `createWindow`, `killWindow`
  • `sendKeys`, `capturePane`, `isPaneRunning`
  • `isTmuxAvailable`, `listSessions`
  • etc.

Every consumer (`orchestrator.ts`, `monitor.ts`, `launch.ts`, `cleanup.ts`) imports directly from `tmux.ts`.

Use Case

  • Zellij users: Growing Zellij adoption; `opencode-zellij-namer` demonstrates feasibility.
  • Lightweight tasks: Simple commands (lint, test, build) don't need full worktree + tmux isolation — a PTY backend would suffice.
  • Testability: Mocking a `Multiplexer` interface is far cleaner than mocking 14 tmux functions.
  • Remote environments: Some CI/cloud environments don't have tmux available.

Proposed Solution

Interface

```typescript
interface Multiplexer {
// Lifecycle
isAvailable(): Promise;
createSession(opts: SessionOpts): Promise; // returns target ID
createWindow(opts: WindowOpts): Promise;
killSession(target: string): Promise;
killWindow(target: string): Promise;

// Interaction
sendKeys(target: string, keys: string): Promise;
captureOutput(target: string, lines?: number): Promise;

// Status
isPaneRunning(target: string): Promise;
sessionExists(target: string): Promise;
listSessions(): Promise<string[]>;

// Hooks
onPaneDied?(target: string, callback: (exitCode: number) => void): void;
}
```

Implementations

  1. `TmuxMultiplexer` — wraps existing `tmux.ts` functions (zero behavior change).
  2. `ZellijMultiplexer` — experimental, leveraging `opencode-zellij-namer` patterns.
  3. `PtyMultiplexer` — lightweight, for simple tasks that don't need full isolation.

Migration path

  1. Define the interface.
  2. Create `TmuxMultiplexer` wrapping existing code (no behavior change).
  3. Update consumers to use the interface.
  4. Add Zellij/PTY implementations later.

Files Involved

  • `src/lib/tmux.ts` — current 14+ tmux functions → becomes `TmuxMultiplexer`
  • `src/lib/orchestrator.ts` — imports tmux directly
  • `src/lib/monitor.ts` — imports tmux directly
  • `src/tools/launch.ts` — imports tmux directly
  • `src/tools/cleanup.ts` — imports tmux directly
  • New: `src/lib/multiplexer.ts` — interface definition

Additional Context

From audit report Section 2 (Where MC Falls Behind): "tmux-only, hardcoded — Should abstract via interface." Section 4: "Multiplexer interface — Abstract tmux behind interface, support Zellij and PTY backends." Section 9 Phase 3 roadmap item.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3: lowNice to have — polish, cleanup, or long-termenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions