@victor-software-house/pi-terminal-env

Tiny zero-dep helpers to detect the terminal emulator pi is running in (iTerm2, tmux, etc.). Pure env-var probes, no I/O.

Packages

Package details

package

Install @victor-software-house/pi-terminal-env from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@victor-software-house/pi-terminal-env
Package
@victor-software-house/pi-terminal-env
Version
0.1.3
Published
May 13, 2026
Downloads
65/mo · 8/wk
Author
victor-founder
License
MIT
Types
package
Size
22.3 KB
Dependencies
0 dependencies · 0 peers

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

@victor-software-house/pi-terminal-env

Tiny zero-dependency probes for detecting the terminal emulator pi is running in. Pure synchronous env-var checks — no I/O, no binary probing, no side effects. Safe to call at module load time from pi extensions, CLIs, postinstall scripts, anywhere.

Every detector cites the env var(s) it relies on and (where available) the vendor source for that signal. When a terminal exposes multiple signals, the detector OR-checks them so it works across:

  • direct GUI launches (every var present),
  • SSH sessions where the GUI emulator's vars may be stripped,
  • tmux / screen passthrough where TERM is rewritten.

Install

pnpm add @victor-software-house/pi-terminal-env

Usage

import {
	isIterm2,
	isCmux,
	isTmux,
	isSsh,
	terminalProgram,
} from "@victor-software-house/pi-terminal-env";

if (isIterm2()) {
	// safe to send iTerm2-specific OSC sequences, call it2api, etc.
}

if (isCmux()) {
	// open the cmux Unix socket, send surface-rename or trigger-flash commands
}

if (!isTmux()) {
	// register /tmux-promote, etc.
}

console.log(terminalProgram()); // "iTerm2" | "cmux" | "Ghostty" | ...

API

GUI emulators

Export Signals checked
isIterm2() TERM_PROGRAM=iTerm.app · LC_TERMINAL=iTerm2 · ITERM_SESSION_ID
isAppleTerminal() TERM_PROGRAM=Apple_Terminal
isCmux() CMUX_BUNDLE_ID=com.cmuxterm.app · CMUX_SOCKET_PATH · CMUX_WORKSPACE_ID · CMUX_SURFACE_ID
isGhostty() TERM_PROGRAM=ghostty · GHOSTTY_RESOURCES_DIR · TERM=xterm-ghostty. Also true inside cmux (cmux embeds Ghostty); use isCmux() first when the distinction matters.
isWezTerm() TERM_PROGRAM=WezTerm · WEZTERM_EXECUTABLE · WEZTERM_PANE
isAlacritty() ALACRITTY_SOCKET · ALACRITTY_LOG · ALACRITTY_WINDOW_ID · TERM=alacritty
isKitty() KITTY_PID · KITTY_WINDOW_ID · KITTY_INSTALLATION_DIR · TERM=xterm-kitty
isKonsole() KONSOLE_VERSION · KONSOLE_DBUS_SERVICE · KONSOLE_PROFILE_NAME
isHyper() TERM_PROGRAM=Hyper
isWarp() TERM_PROGRAM=WarpTerminal
isWindowsTerminal() WT_SESSION · WT_PROFILE_ID
isConEmu() ConEmuPID · ConEmuANSI · ConEmuBaseDir · TERM_PROGRAM=ConEmu
isMintty() TERM_PROGRAM=mintty · MSYSCON=mintty.exe
isTermux() TERMUX_VERSION · PREFIX rooted under /data/data/com.termux
isFoot() TERM starts with foot
isRio() TERM_PROGRAM=rio · TERM=rio

IDE-integrated terminals

Export Signals checked
isVSCode() TERM_PROGRAM=vscode · VSCODE_PID · VSCODE_INJECTION
isCursor() TERM_PROGRAM=Cursor
isJetBrains() TERMINAL_EMULATOR=JetBrains-JediTerm

VTE-family (GNOME stack)

Export Signals checked
isGnomeTerminal() TERM_PROGRAM=gnome-terminal · gnome-terminal-server
isMateTerminal() TERM_PROGRAM=mate-terminal
isXfceTerminal() TERM_PROGRAM=xfce4-terminal
isTerminator() TERM_PROGRAM=terminator
isVTE() VTE_VERSION (any VTE-based terminal — broadest VTE check)

Multiplexers

Export Signals checked
isTmux() TMUX · TERM starts with tmux
isScreen() STY · TERM starts with screen (and not in tmux)
isZellij() ZELLIJ · ZELLIJ_PANE_ID
isMultiplexer() isTmux() ∨ isScreen() ∨ isZellij()

Transport

Export Signals checked
isSsh() SSH_CONNECTION · SSH_CLIENT · SSH_TTY

Composite identification

Export Behavior
terminalProgram(opts) Returns a TerminalProgram union. Defaults to the outermost GUI emulator. Pass { preferMultiplexer: true } to return the multiplexer instead. Falls back to "unknown". cmux is dispatched before Ghostty so cmux sessions are not reported as plain Ghostty.

TerminalProgram union — exact strings returned:

type TerminalProgram =
	| "iTerm2"
	| "Apple_Terminal"
	| "cmux"
	| "Ghostty"
	| "WezTerm"
	| "Alacritty"
	| "kitty"
	| "Konsole"
	| "Hyper"
	| "Warp"
	| "vscode"
	| "Cursor"
	| "JetBrains"
	| "WindowsTerminal"
	| "ConEmu"
	| "mintty"
	| "Termux"
	| "foot"
	| "Rio"
	| "GNOME_Terminal"
	| "MATE_Terminal"
	| "Xfce_Terminal"
	| "Terminator"
	| "VTE"
	| "tmux"
	| "screen"
	| "zellij"
	| "unknown";

Reliability notes

  • No subprocess, no FS, no escape-sequence round-trip. Every detector is O(1) env-var lookup. Safe at module load.
  • SSH passthrough. isIterm2() honours LC_TERMINAL so iTerm2 detection survives SSH when SendEnv LC_* and AcceptEnv LC_* are configured.
  • Multiplexed sessions. terminalProgram() returns the outer GUI emulator by default; multiplexer-inside-emulator returns the emulator. Use { preferMultiplexer: true } to flip.
  • cmux vs Ghostty. cmux embeds Ghostty's terminal core, so isGhostty() is intentionally true inside cmux. Always check isCmux() before isGhostty() when the difference matters (socket commands, surface model, notification rings). terminalProgram() already does this dispatch.
  • Best-effort fallback. When no detector matches, terminalProgram() returns "unknown" rather than guessing.

Design

  • Synchronous env-only — no subprocesses, no filesystem, no network.
  • Zero runtime dependencies.
  • Pi-ecosystem oriented but framework-agnostic — useful in any Node CLI.
  • Every detector documents the env vars it inspects so failure modes are debuggable from printenv alone.

Status

Pre-1.0. API surface may grow; existing exports follow semver.

License

MIT