pt
personal terminal · also written pterm
Your terminal, with the whole project around it.
A Linux terminal workspace — projects, splits, tabs and git in one
window, built on GTK4 and libghostty-vt.
Free, no telemetry, no subscription.
curl -fsSL
https://github.com/hdprajwal/pt/releases/latest/download/install.sh |
sh
What it is
A terminal is usually one window per thing you are doing. pt turns that
around: each project is an entry in the sidebar, and it keeps its own
tabs, splits and working directories. Switch to a project and everything
is where you left it — nothing to reopen, nothing to cd back
into.
The VT layer is libghostty-vt, so escape-sequence handling is someone else's solved problem. The rest is GTK4 and libadwaita.
Features
| projects | Ctrl 1–9 | Each project keeps its own tabs, splits and directories. The layout is written to disk and restored on next launch. |
| palette | Ctrl K | Projects, shells and commands, fuzzy-matched. Keyboard only. |
| splits | Divide a tab as far as you need. New panes inherit the directory you were already in. | |
| selection | Ctrl ⇧ C | Click and drag to select. Double-click a word, triple-click a line. Inside a full-screen app that wants the mouse, hold Shift to select with pt instead. |
| git | Branch, dirty count and last exit code in the statusline; the detail in the info panel. | |
| themes | Config and the active theme are watched on disk and applied live — no restart, no reload command. |
Install
Prebuilt tarballs for Linux x86_64 and aarch64 are published on
GitHub Releases. The installer puts pt in ~/.local/bin, adds
the prompt snippets, and registers a desktop entry and icon so it shows
up in your launcher.
curl -fsSL https://github.com/hdprajwal/pt/releases/latest/download/install.sh | sh
Set PT_PREFIX to change the prefix, or pass a tag as an
argument to pin a version. The runtime libraries still come from your
package manager — GTK4 4.16 or newer, libadwaita and json-glib:
# Arch-based
sudo pacman -S --needed base-devel cmake pkgconf gtk4 libadwaita json-glib
Fonts are not bundled. The defaults are JetBrains Mono for the terminal and IBM Plex Sans for the UI — install them, or point the config at fonts you already have.
Build from source
You also need Zig 0.15.x, CMake 3.19 or newer, and network access on the
first configure — ghostty's lib-vt is fetched at a pinned
commit and built, so the first build takes a while. Later builds are
incremental.
cmake -B build
cmake --build build
./build/pt
ctest --test-dir build # tests
Selecting and copying text
Left-click and drag selects. Double-click selects a word, triple-click
selects a line, and Ctrl+Shift+C copies
(Ctrl+Shift+V pastes). Typing clears the selection and snaps
the view back to the prompt.
Full-screen apps — Claude Code, vim, htop, lazygit, fzf — usually ask the
terminal for the mouse, and pt hands it over. That is what makes their
own mouse features work, including selecting text inside Claude Code,
which copies it for you. Hold Shift while you drag to take
the pointer back for that one gesture and select with pt instead.
The wheel is not part of that deal. An app that asks for the mouse gets
the wheel whatever mouse-reporting says, because scrolling
is not how you select text and an app on the alternate screen leaves pt
nothing to scroll. Holding Shift takes the wheel back and
moves pt's own view.
Set mouse-reporting = false if you would rather a plain drag
always selected pt's own text. The cost is that click-driven features
inside those apps stop working. Either way, "Toggle mouse reporting" in
the palette flips the focused pane for the rest of the session without
touching the config.
When a program copies for you
A program can put text on your clipboard by printing an escape sequence (OSC 52). That is how a yank in nvim over ssh, tmux's copy mode, and selecting text inside Claude Code all reach the clipboard on the machine you are sitting at. pt allows it out of the box.
The same sequence has a second form that asks the terminal what is on the clipboard instead. pt never answers it, at any setting. Anything running in a pane could use it to read what you last copied, including something on the far end of an ssh session.
Set osc52 = ask to approve each one. The dialog says which
pane asked and how many bytes it wants to copy.
osc52 = off ignores clipboard writes completely.
Configuration
pt reads ~/.config/pt/config, a key = value file
where # starts a comment. Those seven keys, plus
app-* colour-token overrides such as
app-background = #101010, are the entire config surface.
theme = pt-dark
font-size = 9
font-family = JetBrains Mono
ui-font-size = 12.5
ui-font-family = IBM Plex Sans
mouse-reporting = true
osc52 = write
Booleans accept true/false,
yes/no, on/off or
1/0. osc52 takes
write, ask or off. Custom themes go in
~/.config/pt/themes/; both the config and the active theme
are watched and applied live.
Shell prompt integration
Source the snippet for your shell from its rc file. Bash and fish
variants live next to the zsh one in share/prompt/.
# ~/.zshrc
source ~/.local/share/pt/prompt/pt-prompt.zsh
The snippet is a no-op outside pt, so sourcing it unconditionally is
safe. Inside pt it reports each command's exit code back to the app and
prints an identity line — path, branch, dirty count — in the project's
accent colour. If a repository with a huge untracked tree makes the
prompt slow, set PT_PROMPT_GIT_UNTRACKED=no to count only
tracked changes.