A config manager for the kitty terminal.
Drives kitty.conf so you can switch themes, manage profiles, snapshot
sessions, and persist font-size changes — from a TUI or a scriptable CLI.
Every mutation goes through the same pipeline: snapshot the existing file,
write the new one, then signal running kitty processes (SIGUSR1) to reread.
You get backups and live reload for free.
- TUI — themes, settings, sessions, keybinds, fonts. Live theme preview on
arrow-key hover (uses
kitty @ set-colors; reverts onescor moving away). - Themes — bundled defaults (Catppuccin-Mocha, Gruvbox-Dark, Nord,
Rose-Pine, Tokyo-Night, Dracula). Install more from a URL, a git repo, or a
local
.conffile. - Profiles — bundle theme + settings + keybinds + fonts into a named directory; apply or share as a unit.
- Persistent zoom —
psps zoom inc/dec/setwritesfont_sizeinto kitty.conf so the change survives reloads and new windows. Bind it in kitty.conf to replace the runtime-onlyctrl++/ctrl+-defaults. - Sessions — capture the current kitty layout, restore it later, or run a
background autosave daemon (
psps autosave start) so the next launch picks up where you left off. The daemon detaches itself — no terminal window needs to stay open — andpsps autosave status/stopmanage it. - Generic key/value —
psps set <key> <value>for any kitty.conf directive, with--dry-runto preview the diff first. - Undo + backups — every write is snapshotted;
psps undorestores the last one. - Opt-in self-update —
psps updatechecks GitHub for a newer release and installs it when psps lives in a writable location; on package-manager installs it prints the rightapt/dnf/pacman/apkupgrade command instead of fighting the package database.psps update enableturns on a cached, once-a-day "update available" notice (off by default — no network calls until you opt in). - Agent-friendly —
--jsonon every command emits a single JSON object on stdout (errors too — agents only parse one stream). SeeAGENTS.mdfor the full agent guide;psps agent-guideprints it to stdout. psps doctor— diagnoses common setup issues (missingallow_remote_control, unreachablelisten_onsocket,pspsnot on PATH).
A POSIX install script that detects your OS/arch, downloads the latest
release, verifies its checksum, and installs to ~/.local/bin:
curl -fsSL https://raw.githubusercontent.com/elythi0n/psps/main/install.sh | sh
# or: wget -qO- https://raw.githubusercontent.com/elythi0n/psps/main/install.sh | shOverride the target dir, or pin a specific release tag (default: latest):
# PSPS_VERSION is optional — omit it to get the latest release.
PSPS_INSTALL_DIR=/usr/local/bin PSPS_VERSION=v0.3.2 \
sh -c "$(curl -fsSL https://raw.githubusercontent.com/elythi0n/psps/main/install.sh)"Installing to a user-writable dir (the default ~/.local/bin) also lets
psps update self-update later — see Updating.
Browse GitHub Releases —
archives for Linux, macOS, and Windows on amd64 and arm64. To grab the
latest without hardcoding a version:
VERSION=$(curl -fsSL https://api.github.com/repos/elythi0n/psps/releases/latest \
| sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p')
curl -L "https://github.com/elythi0n/psps/releases/download/${VERSION}/psps_${VERSION#v}_linux_amd64.tar.gz" | tar xz
sudo install -m 0755 psps /usr/local/bin/pspsVERSION=$(curl -fsSL https://api.github.com/repos/elythi0n/psps/releases/latest \
| sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p')
curl -LO "https://github.com/elythi0n/psps/releases/download/${VERSION}/psps_${VERSION#v}_linux_amd64.deb"
sudo dpkg -i "psps_${VERSION#v}_linux_amd64.deb"VERSION=$(curl -fsSL https://api.github.com/repos/elythi0n/psps/releases/latest \
| sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p')
sudo rpm -i "https://github.com/elythi0n/psps/releases/download/${VERSION}/psps_${VERSION#v}_linux_amd64.rpm"VERSION=$(curl -fsSL https://api.github.com/repos/elythi0n/psps/releases/latest \
| sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p')
curl -LO "https://github.com/elythi0n/psps/releases/download/${VERSION}/psps_${VERSION#v}_linux_amd64.apk"
sudo apk add --allow-untrusted "psps_${VERSION#v}_linux_amd64.apk"A PKGBUILD is included. From a clone:
makepkg -sigo install github.com/elythi0n/psps@latestgit clone https://github.com/elythi0n/psps
cd psps
make install-user # builds and installs to ~/.local/bin
# or:
make install # installs to /usr/local/bin (needs sudo)psps update check # is a newer release out?
psps update # install it (writable installs), else print the right upgrade commandpsps update only self-replaces the binary when it lives in a writable
location (like ~/.local/bin). For package-manager installs it detects the
manager and prints the matching command (apt/dnf/pacman/apk) rather
than overwriting a package-owned file. To get a cached, once-a-day
"update available" notice on launch (off by default):
psps update enableLaunch the TUI:
pspsQuick CLI examples — see psps help for the full list.
# Themes
psps theme list
psps theme apply gruvbox-dark
psps theme install https://github.com/example/my-theme
# Font size that survives reloads
psps zoom inc 2
psps zoom set 14
# Generic kitty.conf edits, with a preview
psps set cursor_blink_interval 0.5 --dry-run
psps set cursor_blink_interval 0.5
# Sessions
psps session save my-layout
psps session restore my-layout
# Autosave: restore where you left off, kept fresh by a background daemon
psps autosave enable # point startup_session at the auto session
psps autosave start # detached daemon — keeps the snapshot fresh, no window needed
psps autosave status # running? last snapshot age?
psps autosave stop
# Updates (opt-in notice; manual apply)
psps update enable # cached, once-a-day "update available" notice
psps update check # check now, report only
psps update # install it (or print your package manager's upgrade command)
# Diagnose your setup
psps doctorAdd to ~/.config/kitty/kitty.conf to replace kitty's runtime-only zoom
defaults with the persistent version:
map ctrl+equal launch --type=background psps zoom inc 2
map ctrl+minus launch --type=background psps zoom dec 2
map ctrl+0 launch --type=background psps zoom set 11
psps autosave start runs a detached daemon, so closing the window that
launched it is fine. It does not start on boot, though — after a reboot you
get restored to where you left off (that's startup_session, which lives in
kitty.conf), but the freshness daemon is off until you start it again.
To bring it up automatically whenever you open a terminal, add this to your
shell rc (~/.zshrc, ~/.bashrc, …):
psps autosave start >/dev/null 2>&1start is idempotent — it checks for an existing daemon and no-ops if one is
already running — so every new shell tries to start it but only the first
actually does. No service manager required.
psps is designed to work cleanly from inside agentic tools (Claude Code,
Cursor, etc.). Every command supports --json, install commands respect
--yes to skip interactive prompts, and the agent guide ships with the
binary.
psps agent-guide # prints AGENTS.md
psps theme list --json | jq '.themes[].name'
psps set font_size 14 --dry-run --json # preview as JSONmake build # → ./build/psps
make test # go test ./...
make fmt # gofmt -w .
make vet # go vet ./...
make lint # golangci-lint run
make staticcheck # honnef.co/go/tools staticcheck
make check # tidy + vet + test + staticcheckThe codebase is a single Go module:
main.go— the bubbletea root model + TUI shellinternal/cli/— non-TUI entry point (thepsps theme apply Xetc. commands)internal/panes/— TUI panels: themes, settings, sessions, keybinds, fontsinternal/kconf/— kitty.conf parser/writer (line-aware, comment-preserving)internal/apply/,backups/,diff/— the write pipelineinternal/themelib/,profile/,sessionlib/— feature librariesinternal/installer/—theme/profile installURL+git+file staginginternal/kitty/— talks to running kitty (SIGUSR1,@ set-colors)internal/updater/— opt-in self-update + GitHub version checkinternal/userconf/— psps's own settings (~/.config/psps/config)internal/ui/,logfile/— shared styling + the opt-in diagnostic log
See CONTRIBUTING.md before opening a PR.