WezTerm Integration
tallow has deep integration with WezTerm. The agent can manage panes and tabs, route sensitive commands to separate terminals, and signal working-session status through visual indicators in the tab bar.
This guide covers the full integration across the wezterm-pane-control
extension, working-session signaling, and the WezTerm Lua configuration
that ties it together.
Pane and tab management
Section titled “Pane and tab management”The wezterm-pane-control extension
registers a single wezterm_pane tool with 10 actions for controlling
WezTerm from natural language prompts.
How it works
Section titled “How it works”The extension checks for the WEZTERM_PANE environment variable at load
time. If present, it registers the tool and injects system prompt context
telling the model which pane it’s running in. Outside WezTerm, the
extension is a silent no-op with zero overhead.
Actions
Section titled “Actions”| Action | What it does |
|---|---|
list | List panes in the current tab with IDs, titles, sizes |
split | Split current pane in any direction, optionally run a command |
close | Kill a pane by ID (defaults to current) |
focus | Activate a pane by ID or direction |
zoom | Toggle or set zoom state |
resize | Adjust pane size directionally |
send_text | Paste text into a target pane |
read_text | Get visible text from a pane |
spawn_tab | Open a new tab with optional command |
move_to_tab | Detach a pane into its own tab |
Common patterns
Section titled “Common patterns”Spawning a parallel tallow session:
"split a new tallow session to the right"→ wezterm cli split-pane --right -- tallow
"open a bottom panel at 30% with haiku"→ wezterm cli split-pane --bottom --percent 30 -- tallow --model haikuRunning commands in other panes:
"run the dev server in the pane to the right"→ split or send_text to target pane with the commandReading output from another pane:
"what does the other pane show?"→ read_text from target pane IDPrivate command execution
Section titled “Private command execution”The agent can route commands through WezTerm panes instead of capturing output through the bash tool. This keeps sensitive output — private keys, tokens, credentials — out of the LLM context window entirely.
When terminal routing is used
Section titled “When terminal routing is used”The extension’s system prompt guidance instructs the model to use its judgment:
- Don’t auto-read commands likely to reveal secrets unless the user explicitly asks
- Execute by default — when prefilling a command for the user, send
Enter (
\n) to run it automatically - Leave unexecuted only when the user explicitly asks to review or edit the command first
- Let the user watch — for commands where the user wants to monitor output, execute in a visible pane and let them read the terminal directly
This is not a hard security boundary. The model uses judgment based on
the tool description and system prompt context. Commands like cat ~/.ssh/id_rsa or op read are routed to a terminal pane rather than
captured by bash.
Working-session signaling
Section titled “Working-session signaling”The wezterm-notify extension signals
agent working-session status to WezTerm via
OSC 1337 SetUserVar
sequences. WezTerm Lua config reads the pi_status user variable to
drive visual indicators.
Lifecycle
Section titled “Lifecycle”Status transitions are tracked at the agent session level and coalesced across overlapping lifecycle events:
| Lifecycle edge | pi_status | Effect |
|---|---|---|
before_agent_start / agent_start | working | Enter working once (duplicate starts coalesce) |
agent_end | done | Inactive tab turns blue |
input while working | (unchanged) | Avoids mid-run flicker |
input while idle, session_start, session_shutdown | (cleared) | Reset to neutral |
Entering working emits an immediate pi_heartbeat, then pulses
continue every 500ms while working to trigger WezTerm redraws.
OSC stripping
Section titled “OSC stripping”When OSC 1337 sequences appear in bash output (from programs like bun test or nvim-treesitter), tallow strips them before display to prevent line-width calculation errors:
bash-tool-enhanced—stripNonDisplayOsc()removes all non-hyperlink OSC sequences from captured outputtallow-tui—visibleWidth()strips OSC sequences when calculating terminal column widths
Tab bar indicators
Section titled “Tab bar indicators”The WezTerm Lua configuration consumes pi_status to show visual
feedback in the tab bar. These indicators work across all panes in a
tab — if any pane has an active agent, the tab shows it.
Spinner (working session in progress)
Section titled “Spinner (working session in progress)”When any pane in a tab has pi_status=working:
- A spinner animation (
◰ ◳ ◲ ◱) appears before the tab title - Frame advancement is deterministic: one step per redraw while any
pane is
working(heartbeat provides the redraw cadence) - Color: amber (
#d8a274)
Done indicator (unseen result)
Section titled “Done indicator (unseen result)”When at least one pane has pi_status=done and the tab is not
active (user hasn’t seen the result):
- Tab title turns blue (
#61afef) - Tracks “seen” state per pane in
wezterm.GLOBAL.pi_seen - Resets when: agent re-enters a working session, user switches to the
tab, or the pane loses
pi_status
Normal states
Section titled “Normal states”- Active tab: yellow (
#ccb266) with underline - Inactive tab: gray (
#737373)
Status bar integration
Section titled “Status bar integration”The right status bar can show contextual information:
- Git branch with ahead/behind counts
- Process name of the foreground process
- Focus zoom indicator when zoom mode is active
- Workspace numbers when multiple workspaces exist
WezTerm Lua setup
Section titled “WezTerm Lua setup”tallow ships a Lua module that handles the WezTerm side. Copy or symlink it into your WezTerm config directory, then require it:
# Symlink into WezTerm configln -s "$(dirname "$(which tallow)")/../lib/node_modules/tallow/extensions/wezterm-notify/wezterm/tallow.lua" \ ~/.config/wezterm/tallow.lua-- In your wezterm.luarequire("tallow").setup()That registers format-tab-title and update-right-status handlers
for the spinner and done-color indicators.
Custom colors
Section titled “Custom colors”require("tallow").setup({ spinner_color = "#d8a274", -- spinner while working (default: amber) done_color = "#61afef", -- tab color for unseen results (default: blue) active_color = "#ccb266", -- active tab color (default: yellow) inactive_color = "#737373", -- inactive tab color (default: gray)})Advanced: integrate with existing handlers
Section titled “Advanced: integrate with existing handlers”setup() owns both format-tab-title and update-right-status.
If you already define either handler, compose manually with helpers:
local tallow = require("tallow")
wezterm.on("update-right-status", function(window, pane) tallow.tick() -- your existing update-right-status logicend)
wezterm.on("format-tab-title", function(tab) local any_working, any_done_unseen = tallow.get_tab_status(tab) local title = tostring(tab.tab_index + 1) local elements = {}
if any_working then table.insert(elements, { Foreground = { Color = "#d8a274" } }) table.insert(elements, { Text = " " .. tallow.spinner_char() .. " " }) else table.insert(elements, { Text = " " }) end
local fg = tab.is_active and "#ccb266" or "#737373" if any_done_unseen then fg = "#61afef" end
table.insert(elements, { Foreground = { Color = fg } }) table.insert(elements, { Text = " " .. title .. " " }) return elementsend)Workspaces
Section titled “Workspaces”WezTerm’s workspace feature lets you organize groups of tabs. The status bar shows numbered workspace indicators when multiple workspaces exist, and you can switch between them with keybindings.
The wezterm_pane tool does not currently have workspace actions — pane
and tab management operate within the current workspace. Workspace
switching is a user-side operation through WezTerm keybindings.
Putting it together
Section titled “Putting it together”A typical WezTerm + tallow setup:
- Install tallow — follow the installation guide
- Configure WezTerm Lua — symlink
tallow.luaand callrequire("tallow").setup()(or manually compose with helpers) - Run tallow in WezTerm — the extension auto-detects via
WEZTERM_PANEand activates
The agent can then split panes, spawn sessions, route commands, and you’ll see spinner/done indicators in the tab bar as it works.
Related
Section titled “Related”wezterm-notify— the extension that emits working-session signalswezterm-pane-control— pane and tab management toolbash-tool-enhanced— OSC stripping for clean bash output- WezTerm shell integration docs — upstream SetUserVar protocol reference