PrismTTY is a fast terminal output highlighter focused on network devices and Linux/Unix administration. It is intended as a ChromaTerm-style CLI wrapper with network-focused built-in profiles.
Website: prismtty.com.
Current version: 0.2.1.
Synthetic terminal previews using documentation-only hostnames and addresses:
Install the latest release from the PrismTTY Homebrew tap:
brew install inxbit/tap/prismttyThe Homebrew formula installs prismtty, ptty, ct, bundled profiles, and
shell completions. It also installs the required PCRE2 runtime dependency.
Install from crates.io:
cargo install prismttyCargo builds PrismTTY from source and installs the command binaries. You need
Rust 1.85 or newer plus PCRE2 and pkg-config available on your system.
For cargo install on macOS, install the native build dependencies first:
brew install pcre2 pkg-configFor cargo install on Debian/Ubuntu, install:
sudo apt-get install libpcre2-dev pkg-configPrebuilt release archives and checksums are available on the v0.2.1 release page.
Each release archive contains the binaries, license/readme files, example
profiles, shell completions, and a .tar.gz.sha256 checksum.
Build from a checkout with:
cargo build --releaseThe project builds these user-facing binaries:
prismttypttyct
Release packages can be built with:
scripts/package-release.sh darwin-aarch64The release workflow generates a Homebrew formula from the actual release
checksums and uploads it as prismtty.rb with the release artifacts. The
published tap formula lives in
inxbit/homebrew-tap.
ptty /bin/zsh
ptty ssh router.example.net
show-tech.txt | prismtty --profile cisco
prismtty profiles test cisco fixtures/cisco.txt
prismtty --reloadThe recommended interactive workflow is to start one wrapped shell from your terminal profile:
ptty /bin/zshFrom inside that shell, run normal ssh, telnet, or console-wrapper commands.
PrismTTY dynamically switches profiles from observed login banners and prompts,
then keeps the selected remote profile locked for the session. Normal command
output such as interface descriptions cannot churn the profile in the middle of
the session. Nested remote sessions are still supported: a typed remote-jump
command arms the next strong banner or repeated prompt to push a new profile, and
connection-close markers pop back to the previous profile.
Interactive mode is designed to preserve shell line editing and typed command
echo, including zsh prompts that use decorative Unicode prompt markers such as
╰─○, ❯, or ➜.
Use pipe mode for noninteractive output:
show-tech.txt | prismtty --profile cisco
journalctl -xe | prismtty --profile linux-unixImportant options:
-p, --profile <name>forces one or more profiles.--no-auto-detectuses onlygenericunless profiles are forced.--no-dynamic-profiledisables profile switching inside wrapped interactive shells.-c, --config <file>loads a ChromaTerm-compatible YAML file.--strip-ansiremoves existing ANSI before PrismTTY styles output.--show-profileprints profile selections and transitions to stderr.--local-echolocally echoes printable typed keys for no-echo device sessions.--trace-io <file>appends hex-encoded PTY input/output plus rendered-output diagnostics.-R, --rgbforces RGB color output.--pcreis accepted for ChromaTerm compatibility; PCRE2 is always used.-b, --benchmarkprints per-rule timing and match-count data.-r, --reloadasks running PrismTTY sessions to reload config.
Profile commands:
prismtty profiles list
prismtty profiles show cisco
prismtty profiles validate ~/.config/prismtty/profiles.d/my-vendor.yml
prismtty profiles test cisco fixtures/cisco.txtPrismTTY loads built-in profiles first, then user rules. By default it checks:
~/.chromaterm.yml~/.chromaterm.yaml~/.config/chromaterm/chromaterm.yml~/.config/chromaterm/chromaterm.yaml~/.config/prismtty/config.yml~/.config/prismtty/config.yaml/etc/chromaterm/chromaterm.yml/etc/chromaterm/chromaterm.yaml~/.config/prismtty/profiles.d/*.yml~/.config/prismtty/profiles.d/*.yaml
ChromaTerm-style rules are supported directly:
rules:
- description: IPv4
regex: '\b192\.0\.2\.\d+\b'
color: f#00ffffNative profile files add metadata:
profile:
name: custom-router
inherits: [generic]
detection:
- CustomOS
rules:
- description: custom interface
regex: '\bcust\d+/\d+\b'
color: f#00ffff boldProfiles under ~/.config/prismtty/profiles.d/ are first-class profiles: they
appear in profiles list, can be shown with profiles show, can inherit built-in
or other user profiles, and participate in auto-detection through their
detection hints.
Built-in profiles are bundled data-driven profile files compiled into the binary.
Their private runtime detection metadata is intentionally not part of the public
user profile schema yet. If a user profile under profiles.d includes
profile.runtime, profiles validate and normal startup loading reject it as a
reserved field.
Long-running ptty /bin/zsh sessions register themselves in a small runtime
directory under /tmp by default. Run this after editing ~/.chromaterm.yml or
files under ~/.config/prismtty/:
prismtty --reloadThe next output chunk in each running PrismTTY session reloads the active config.
Set PRISMTTY_RUNTIME_DIR to override the runtime directory, which is useful for
tests or isolated sessions.
genericjuniperciscoarubacxversaaristafortinetpalo-altolinux-unix
These profiles are clean-room curated rule sets for prompts, interfaces, addresses, protocol states, syslog severity, operational status, counters, and common vendor terms.
The built-in rule sets and detection hints live as bundled profile data rather
than hardcoded vendor branches. Adding or adjusting a built-in profile should
start from the bundled profile file and its tests, while user profiles continue
to use the public schema shown above. Bundled runtime metadata can also include
private negative_signals that block only startup prompt matcher detection; weak
detection hints, strong banner signals, and runtime prompt transitions are not
blocked by those exclusions.
Interactive dynamic mode keeps built-in vendor selection conservative: after a
specific profile such as generic, cisco or generic, juniper is selected,
normal command output cannot add another vendor profile. Strong login banners can
still switch profiles, and typed nested remote commands can switch after the next
strong banner or repeated prompt. Fortinet is intentionally more permissive only
from a local-shell baseline: a single hostname # Fortinet prompt can promote to
generic, fortinet, which supports local shell wrappers such as fw that do not
show a FortiOS banner or an explicit ssh command. Other prompt-only vendor
switches still require repeated evidence or a typed remote-jump command.
When PrismTTY is launched as an iTerm profile command, it strips iTerm's native
shell-integration variables from the child shell to avoid nested integration
marks. The stripped values are preserved under PRISMTTY_PARENT_* names for
dotfiles that need session or profile context. For example:
_iterm_session_id="${ITERM_SESSION_ID:-${PRISMTTY_PARENT_ITERM_SESSION_ID:-}}"
if [[ $_iterm_session_id =~ w[0-9]+t0p0 ]]; then
fastfetch
fiThe CLI entry point is intentionally split into focused internal modules:
src/cli.rskeepsrun(), action dispatch, and CLI error handling.src/cli/args.rsowns the clap-backed parser and parser contract tests.src/cli/profile_selection.rsloads profile stores, user config, color mode, and profile reporting.src/cli/pty.rsowns PTY command execution, raw mode, stdin forwarding, local echo, the iTerm environment guard, and resize polling.src/cli/stream.rsowns streaming highlight orchestration, dynamic profile observation, reload handling, benchmarks, andHighlightSession.src/cli/runtime.rsowns runtime registration and reload markers.src/cli/trace.rsowns--trace-ioformatting.
Keep these modules internal to the CLI tree. Parser contract tests intentionally
preserve current behavior, including --pcre as a no-op compatibility flag, so
future parser migrations can be checked without changing user-facing semantics.
The data-driven profile refactor did not keep a temporary old/new detector
compatibility module; instead, the current safety net is the runtime transition
tests plus byte-for-byte Cisco and Juniper streaming snapshots.
Run the built-in throughput benchmark example:
cargo run --release --example throughputThe example runs router dump, syslog, and mixed-ANSI samples. Runtime benchmark mode is available in normal use:
show-tech.txt | prismtty --benchmark --profile cisco >/dev/nullReplay fixtures under fixtures/replay/ are synthetic. They exist to protect
profile detection and streaming coloring behavior across chunk boundaries without
checking private device output into the repository.
Run the replay suite with:
cargo test --test replayWhen adding a new replay case, use invented hostnames, documentation-range IP addresses, and minimal command output that preserves only the token shape needed for the rule under test. Do not copy real terminal captures into this directory.
MIT. See LICENSE.