# How nodeterm Uses the tmux paste-buffer -p Command for Reliable Multi-Line Input

> Discover how nodeterm uses tmux paste-buffer -p for reliable multi-line input across all tmux versions. Learn about its bracketed-paste framing delegation.

- Repository: [eneskirca/nodeterm](https://github.com/eneskirca/nodeterm)
- Tags: internals
- Published: 2026-08-26

---

**The `paste-buffer -p` command in nodeterm delegates bracketed-paste framing decisions to tmux itself, ensuring multi-line text transmits correctly across all tmux versions without relying on version-specific variable probes.**

The `nodeterm` project runs each terminal session inside a persistent **tmux** pane to maintain state and enable agent communication. When transmitting multi-line commands or agent payloads, the application must handle **bracketed-paste mode** correctly to prevent mangled input. The `paste-buffer -p` command provides a version-independent mechanism that respects the target pane's actual paste mode state.

## The Problem with Version-Dependent Bracketed-Paste Detection

Earlier implementations of nodeterm's tmux integration attempted to detect bracketed-paste support by probing the tmux variable `#{bracket_paste_flag}`. This approach proved fragile because the variable only returns accurate values on **tmux 3.7 and newer**. On older versions commonly deployed in production environments (3.4, 3.2, 3.3, etc.), this probe always returns false.

When the probe fails, applications fall back to raw newline insertion using `\r` terminators instead of `\n`. This causes multi-line input to split incorrectly, breaking agent integrations with Claude, Codex, Gemini, and other AI systems that expect properly framed payloads. According to the source analysis in [`CLAUDE.md`](https://github.com/eneskirca/nodeterm/blob/main/CLAUDE.md), this created the historic "multi-line write mangles" bug that affected agent message delivery.

## How paste-buffer -p Solves Version Compatibility

The robust solution implemented in nodeterm removes version detection entirely by leveraging tmux's native paste handling through the `-p` flag.

### Delegating Framing Decisions to tmux

The `-p` flag instructs tmux to wrap buffer contents with bracketed-paste escape sequences (`\e[2004h` and `\e[2004l`) **only if** the application inside the target pane has explicitly requested bracketed-paste mode. This delegates the decision to the tmux server, which maintains accurate state information regardless of version.

When the pane does not request bracketed paste, tmux transmits the text unchanged without adding escape sequences. This eliminates the need for nodeterm to query `#{bracket_paste_flag}` or maintain version-specific code paths. As implemented in the source code, this approach works uniformly across tmux 3.2 through 3.7 and future releases.

### Handling Copy-Mode Edge Cases

The command also addresses interactions with tmux's copy-mode. When a pane enters copy-mode (for scrolling or selection), raw paste operations might behave unpredictably or insert text into the scrollback buffer rather than the active prompt.

Nodeterm guards against this by prepending a conditional check to cancel copy-mode before executing the paste operation. This ensures the payload reaches the active shell regardless of the pane's current state.

## Implementation in nodeterm Source Code

The integration appears throughout nodeterm's core modules, with specific implementations handling different payload types.

### Constructing the Command in pty-manager.ts

In [`src/core/pty-manager.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/pty-manager.ts), the `sendText` implementation constructs a compound tmux command that loads text into a temporary buffer, conditionally exits copy-mode, and executes the paste operation with proper flags.

```typescript
// src/core/pty-manager.ts (excerpt)
const cmd = `tmux load-buffer -b nt - \\; if-shell -F -t ${target} '#{pane_in_mode}' 'send-keys -t ${target} -X cancel' \\; paste-buffer -d -p -r -b nt -t ${target}`;

```

This command sequence performs three critical operations:
- **`load-buffer -b nt`** – Loads the payload into a temporary buffer named `nt`
- **`if-shell '#{pane_in_mode}'`** – Detects if the pane is in copy-mode and cancels it
- **`paste-buffer -d -p -r`** – Pastes with delete-after (`-d`), bracketed-paste support (`-p`), and newline preservation (`-r`)

The `-r` flag specifically ensures that newlines remain as `\n` characters rather than being converted to carriage returns, which preserves multi-line command structure.

### Agent Message Delivery

The same mechanism appears in [`src/core/agents/agent-message.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/agents/agent-message.ts) when delivering JSON payloads to AI agents. By routing all agent communication through `paste-buffer -p`, nodeterm guarantees that structured data arrives intact without frame corruption or line-ending translation errors.

```typescript
// src/core/agents/agent-message.ts (conceptual excerpt)
// Payload is first written to tmux buffer, then delivered via:
tmux paste-buffer -p -b agent_buffer -t ${target_pane}

```

### High-Level Architecture Documentation

The design rationale appears in [`src/core/tmux-naming.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/tmux-naming.ts), which documents how the `-p` flag removes the "bracket-paste question" by eliminating version-dependent probes. This file serves as the architectural reference for why nodeterm prefers delegated paste handling over manual escape sequence injection.

## Verification and Testing

The project includes integration tests in [`src/core/tmux-paste.realtmux.test.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/tmux-paste.realtmux.test.ts) that validate `paste-buffer -p` behavior across supported tmux versions. These tests confirm that the command correctly frames text on older tmux installations (3.2, 3.3, 3.4) while maintaining compatibility with newer releases.

The test suite specifically verifies that multi-line payloads containing `\n` characters arrive at the target application without mangling, proving that the `-p` flag removes the version-specific limitations that previously affected nodeterm's tmux integration.

## Summary

- The `tmux paste-buffer -p` command delegates bracketed-paste framing to the tmux server, eliminating version-dependent variable probes.
- This fixes multi-line input mangling on tmux versions older than 3.7 by ensuring proper `\n` preservation and escape sequence handling.
- Nodeterm implements this in [`src/core/pty-manager.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/pty-manager.ts) with a compound command that also handles copy-mode cancellation.
- Agent messages in [`src/core/agents/agent-message.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/agents/agent-message.ts) rely on the same mechanism for reliable JSON payload delivery.
- Integration tests in [`src/core/tmux-paste.realtmux.test.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/tmux-paste.realtmux.test.ts) verify correct behavior across all supported tmux versions.

## Frequently Asked Questions

### What does the `-p` flag do in tmux paste-buffer?

The `-p` flag instructs tmux to examine the target pane's bracketed-paste state and automatically wrap the buffer contents with `\e[2004h` (start paste) and `\e[2004l` (end paste) escape sequences only when the underlying application has requested bracketed-paste mode. If the pane does not support or request this mode, tmux transmits the raw text without escape sequences.

### Why did older nodeterm versions struggle with multi-line input?

Previous implementations probed `#{bracket_paste_flag}` to detect paste mode support, but this variable only returns accurate values on tmux 3.7+. On older versions, the false negative caused nodeterm to use `\r` line endings instead of `\n`, splitting multi-line commands into fragmented inputs that broke agent parsing and shell execution.

### How does nodeterm prevent paste operations from interfering with copy-mode?

The command constructed in [`src/core/pty-manager.ts`](https://github.com/eneskirca/nodeterm/blob/main/src/core/pty-manager.ts) includes an `if-shell` guard that checks `#{pane_in_mode}`. When copy-mode is active, the command first executes `send-keys -X cancel` to exit scrollback/selection mode before invoking `paste-buffer -p`, ensuring text always reaches the active command line.

### Which tmux versions support the paste-buffer -p functionality?

The `-p` flag for bracketed-paste awareness works reliably across all tmux versions supported by nodeterm, including 3.2, 3.3, 3.4, and 3.7+. Because the flag delegates framing logic to the tmux server rather than querying version-specific variables, it provides consistent behavior regardless of the host system's tmux installation age.