discord_terminal_presence

module
v0.1.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 16, 2026 License: MIT

README

Terminal Presence mark

Terminal Presence (termp)

Let friends see what you are building, right from your Discord profile.

Go

termp shows the terminal tool you are using—Claude Code, Vim, lazygit, and dozens more—as Discord Rich Presence. It runs quietly on your computer and needs no Discord bot or token.

termp showing your active terminal tool as Discord Rich Presence, cycling through Claude Code, Codex CLI, Gemini CLI, Aider, and Ollama

See it in about 30 seconds

Install with the one-line shell installer on macOS or Linux — see Install below for Homebrew, Windows, and other options, including building from source — then run setup and start:

curl -fsSL https://termp.polter.sh/install.sh | sh
termp setup
termp start

termp start launches the service in the background and returns immediately. Open a supported tool such as nvim, claude, or lazygit, and check your Discord profile. Discord's desktop app needs to be running. To preview the card in your terminal instead, run termp watch.

The setup wizard creates your config, asks before enabling start-at-login, and keeps folder names hidden unless you choose otherwise.

Install

Shell installer — macOS and Linux

curl -fsSL https://termp.polter.sh/install.sh | sh

The installer downloads the matching release archive, verifies its SHA-256 checksum, and installs termp to /usr/local/bin.

Homebrew Cask

brew install --cask polter-dev/tap/termp

The Cask is published from the polter-dev/homebrew-tap.

scoop bucket add polter-dev https://github.com/polter-dev/scoop-bucket
scoop install termp

To upgrade after exiting termp:

scoop update termp

Release downloads

Download the files for your platform from the latest GitHub release. macOS and Linux archives are named termp_VERSION_OS_ARCH.tar.gz, Linux packages use termp_VERSION_OS_ARCH.deb or .rpm, and Windows archives use termp_VERSION_windows_ARCH.zip. VERSION has no leading v. On Windows, prefer Scoop because archive installs cannot self-update; to upgrade an archive install, download and replace it with the new release archive.

From source

go install github.com/polter-dev/discord_terminal_presence/cmd/termp@latest
# Windows also needs the companion launcher beside termp.exe:
go install -ldflags="-H=windowsgui" github.com/polter-dev/discord_terminal_presence/cmd/termpw@latest

This builds termp and puts it in your Go bin directory. If your shell cannot find the command, make sure that directory is on your PATH. This source install works on Windows, macOS, and Linux.

On Windows, keep termpw.exe beside termp.exe. The companion launcher lets Task Scheduler start the daemon without a persistent console window. For a hand-assembled build from a checkout, build both commands separately, then copy both executables to the same stable installation directory:

go build ./cmd/termp
go build -ldflags="-H=windowsgui" ./cmd/termpw
$installDir = Join-Path $env:LOCALAPPDATA "Programs\termp"
New-Item -ItemType Directory -Force $installDir
Copy-Item termp.exe, termpw.exe $installDir

Everyday commands

Running termp by itself opens the live watch view only when standard input and output are interactive terminals. Otherwise it prints help and exits with status 2; use termp watch --once for a non-interactive snapshot.

Command What it does
termp start Starts the presence service in the background after confirming daemon readiness. Use --foreground (-f) to keep it attached.
termp stop Stops the running service and cleans up its process-ID file.
termp connect Asks the running daemon to re-establish Discord IPC now. Already connected is a no-op; use --force to reconnect anyway. Currently implemented on Windows only.
termp status Checks the service, Discord connection, start-at-login, config, warnings, and detected tool.
termp watch Opens a live terminal preview. Use --once for one snapshot.
termp autostart <install|uninstall|enable|disable|status> Manages start-at-login with grouped actions.
termp install Alias for termp autostart install: installs start-at-login and starts termp using a Windows scheduled task, macOS LaunchAgent, or Linux systemd user service. It does not install the binary.
termp uninstall Removes start-at-login only. It does not remove termp data or the binary.
termp uninstall --all Stops the validated daemon, removes start-at-login, shell completions, config, state, cache, and the platform log, then prints the correct command to remove the binary. Confirms first unless --yes is supplied.
termp enable / termp disable Resumes or pauses start-at-login without removing it.
termp settings Opens the interactive settings menu.
termp setup Runs first-time setup; without an interactive terminal, writes the config, skips autostart, and prints the next steps.
termp config init Writes a commented sample config. Add --force to replace an existing config.
termp completion <bash|zsh|fish> Prints a tab-completion script for your shell.
termp version Prints the version, commit, build date, Go version, OS, and architecture.
termp update Checks for a newer release and updates Homebrew, Go, deb/rpm, and macOS/Linux shell/binary installs as appropriate. Windows archive installs are not self-updated; termp prints the command to run.

termp watch, termp settings, and the interactive setup wizard need a real terminal window. Applying setup reconciles start-at-login in both directions: enabling it installs autostart, disabling an existing setting removes autostart, and leaving it unchanged does not run a service-manager operation.

If termp cannot find Discord IPC in an unusual WSL, container, or newly packaged setup, set DISCORD_IPC_PATH to the socket file or its containing directory on Unix, or to the named-pipe path on Windows.

Global flags:

Flag What it does
--verbose, -v Enables verbose logging, for example termp --verbose start.
--version Prints the version and exits.

Shell completion

Generate and install tab completion for your shell:

# bash
termp completion bash > ~/.local/share/bash-completion/completions/termp

# zsh
termp completion zsh > ${fpath[1]}/_termp

# fish
termp completion fish > ~/.config/fish/completions/termp.fish

To enable completion only for the current session, use source <(termp completion bash) in bash, source <(termp completion zsh) in zsh, or termp completion fish | source in fish. Each generated script starts with these instructions as comments, so it remains safe to redirect to a file.

Start automatically

Start-at-login is optional and works on Windows, macOS, and Linux:

termp install           # install the login service and start it
termp disable           # pause it without removing it
termp enable            # resume it
termp uninstall         # remove start-at-login only
termp uninstall --all   # remove all termp-created data

On Windows, this creates and immediately runs the Task Scheduler task \Terminal Presence\termp; it runs again when the current user logs in. On macOS, this creates ~/Library/LaunchAgents/dev.termp.daemon.plist, restarts termp after a crash, and writes logs to ~/Library/Logs/termp.log. On Linux, it creates ~/.config/systemd/user/termp.service and enables and starts the systemd user service.

For complete removal, termp uninstall --all shows its plan and asks for confirmation; pass --yes to skip the prompt. It safely stops the termp daemon, removes start-at-login, installed shell completions, config, state and cache files, and the platform log. The command is safe to run again. It never deletes the binary; instead, it prints the command for the detected install method so a package-managed install is removed without leaving its package database inconsistent.

Your privacy

termp has no telemetry and does no tracking. Presence details go only to the Discord desktop app on your computer. There is no bot token: the built-in Discord Application ID (1523168764793847918) is public, safe to share, and is not a password or secret.

Your directory is hidden by default. If you opt in with show_directory = true, you can restrict what appears with directory_allowlist; directory_basename_only = true shows only the folder name rather than its full path.

By default, termp status and termp version make an anonymous, unauthenticated request to GitHub Releases at most once every 24 hours to look for a newer version. The request contains no machine or install ID, usage data, or config contents; its User-Agent is only termp/<version>.

To turn that check off, set the NO_UPDATE_CHECK environment variable (any value, including an empty one) or add update_check = false to your config. Either setting is enough.

Updates

Run termp update to check for a newer release and update using the detected install method. Homebrew installs use brew upgrade, source installs use go install for the new release, and macOS/Linux shell/binary installs reuse the install script. For detected deb/rpm installs, termp downloads the matching package and checksums.txt, verifies the package's SHA-256 integrity, then runs sudo apt install -y for deb, or the first RPM front-end found on the system (dnf, zypper, yum, then rpm -U) for rpm. Scoop installs are not self-updated; after exiting termp, run scoop update termp. termp update detects Scoop installs and prints that command. Windows archive installs cannot self-update; download the new release archive or use go install. Automatic updates are opt-in with auto_update = true; they run silently when termp start launches, never delay daemon startup, and take effect next start.

About the packaged installer

install.sh pins an exact release tag, uses HTTPS throughout to download the matching binary and checksums.txt, verifies the binary's SHA-256, and installs it to /usr/local/bin. Please inspect the script before running it, as you should with any install script.

Each packaged install—or direct download of a release binary—adds to GitHub's anonymous, aggregate download tally. The tally contains no identifier, IP address, or data from your machine; it is simply a small vanity/resume statistic for termp's student maintainer.

termp itself still sends no telemetry, and nothing is collected from the running app.

Configuration

Your config lives at ~/.config/termp/config.toml, or at $XDG_CONFIG_HOME/termp/config.toml when XDG_CONFIG_HOME is set. termp creates the directory when it starts and reloads changes automatically. If an edit is invalid, it keeps the last good config; unknown settings appear as warnings in termp status. When several valid saves happen before the daemon handles a reload notification, they are coalesced so the newest config is applied.

Presence and display settings hot-reload without restarting the daemon. This includes scan_interval, idle_clear_timeout, pin, headliner_idle_timeout, activity_switching, custom_tools, display and privacy settings, CTA settings, and per-tool overrides. A changed scan interval takes effect on the running scan ticker immediately. Reloading detector settings preserves continuous process episodes (identified by tool, PID, and process creation time), so elapsed timers do not restart for processes that remain present. Episode state is written atomically; temp files left by interrupted writes are removed after they have been stale for an hour.

Create a fully commented starter config with:

termp config init          # keep an existing config
termp config init --force  # replace an existing config

Global options

Key Type Default Meaning
enabled bool true Main on/off switch. When false, no presence is shown.
update_check bool true Checks GitHub Releases in termp status and termp version; set false to disable.
auto_update bool false Silently installs newer releases when termp start launches; the update takes effect next start.
scan_interval duration "3s" How often termp scans running tools. Invalid or zero values fall back to 3 seconds.
idle_clear_timeout duration "20m" Clears presence after terminal inactivity lasts this long. On Windows, losing foreground starts that clock and CPU inactivity corroborates it. Set "0" to disable; quiet work can appear idle.
pin string "" ID of a running tool that should always take the spotlight.
headliner_idle_timeout duration "60s" How long the spotlighted tool must be idle before another can replace it.
activity_switching bool true Allows a busier tool to take the spotlight after the current tool becomes idle.

On Windows, idle detection associates activity with a terminal window and uses the system-wide input timer. Its granularity is per terminal window, not per tab: a tool in a background tab of the focused Windows Terminal window reads as active. Software that injects input, such as keep-awake tools and some peripheral suites, can also keep the timer pinned and prevent presence from idle-clearing. macOS and Linux are unaffected because they read the atime of the specific terminal device.

Display options ([display])

Key Type Default Meaning
tool_name bool true Shows the tool's identity everywhere in the presence card: Using <tool name> on the detail line, the tool name as the presence header and large-image tooltip, and the tool icon as the large image. Off, the header becomes "Terminal Presence", no large or small image is sent (Discord falls back to the app icon), and the detail line drops to the fallback message.
elapsed_timer bool true Shows how long the tool has been running.
small_image bool true Uses the top “also running” tool as the small icon.
collection bool true Lists other running tools as also: ... when no folder is shown.
buttons bool true Shows buttons on the presence; Discord allows at most two.

Privacy options ([privacy])

Key Type Default Meaning
show_directory bool false Shows the folder only when enabled and allowed.
directory_allowlist string[] [] Allowed folders by path prefix (~ works). Empty allows any folder.
directory_basename_only bool true Shows the folder name instead of its full path.

Button options ([cta])

Key Type Default Meaning
enabled bool true Adds a termp button when fewer than two tool buttons are already visible.
label string "What is this?" Text on the button.
url string "https://termp.polter.sh/" Link opened by the button.

Per-tool overrides ([tools.<id>])

For a specific tool ID, you can override enabled, tool_name, elapsed_timer, small_image, show_directory, directory_allowlist, directory_basename_only, and buttons. Buttons are a list of { label, url } pairs that replace that tool's defaults.

Custom tools ([[custom_tools]])

Key Type Required Meaning
id string yes Tool ID. Reusing a built-in ID overrides it.
display_name string yes Name shown in Discord.
match.name string one match Exact program name, ignoring case.
match.regex string one match Pattern matched against the program path and command line, ignoring case.
exclude string no Pattern that rejects matching process paths or command lines, ignoring case.
image_url string one image URL of an image to use.
image_key string one image Key of an image uploaded to Discord.
icon_slug string one image Logo name that termp looks up automatically.
icon_source string no Logo source: simpleicons (default) or lobehub.
priority int no Higher values win when several tools match.
buttons array no Default buttons; only two reach Discord.

Choose one image setting. If several are present, termp prefers image_url, then image_key, then icon_slug.

Example config

enabled = true
update_check = true
auto_update = false
scan_interval = "3s"
idle_clear_timeout = "20m"
pin = "codex-cli"
headliner_idle_timeout = "60s"
activity_switching = true

[display]
tool_name = true
elapsed_timer = true
small_image = true
collection = true
buttons = true

[privacy]
show_directory = false
directory_allowlist = ["~/dev", "~/work/oss"]
directory_basename_only = true

[tools.claude-code]
show_directory = true
directory_allowlist = ["~/dev/oss"]
buttons = [
  { label = "Claude Code", url = "https://claude.com/claude-code" },
]

[tools.gemini-cli]
enabled = false

[[custom_tools]]
id = "lazygit"
display_name = "lazygit"
match = { name = "lazygit" }
icon_slug = "lazygit"
icon_source = "simpleicons"

Supported tools

termp recognizes 48 tools out of the box:

Category Tools
AI CLIs Claude Code, Gemini CLI, Codex CLI, aider, Ollama
Editors Neovim, Vim, Emacs, Helix, nano, micro, Kakoune
Multiplexers tmux, Zellij, GNU Screen
Git lazygit, GitUI, tig
Files Yazi, ranger, nnn, lf, Midnight Commander, broot
Monitors htop, btop, Glances, bottom, gtop, bpytop
Containers / K8s k9s, lazydocker, ctop, kubectl tui
Disk & tasks ncdu, gdu, Taskwarrior, calcurse
Messaging & media NeoMutt, WeeChat, Irssi, cmus, ncmpcpp, spotify-tui, spotify_player
Network & utilities gping, bandwhich, dust

Need another one? Add it with [[custom_tools]].

How it works

termp start scans the processes running on your computer, matches them against its built-in and custom tool list, and sends the chosen activity to the Discord desktop app over Discord IPC. Nothing is sent to a termp server.

When several known tools are running, one takes the spotlight and up to three more appear as also: .... A busier tool can take over after the current one has been idle for headliner_idle_timeout; set pin = "<tool-id>" to keep a favorite in the spotlight whenever it is running.

License

Released under the MIT License.

Directories

Path Synopsis
cmd
termp command
termpw command
The companion launcher is a Windows-only artifact.
The companion launcher is a Windows-only artifact.
internal
completioninstall
Package completioninstall installs generated shell completion scripts.
Package completioninstall installs generated shell completion scripts.
terminaltext
Package terminaltext sanitizes externally derived text before terminal output.
Package terminaltext sanitizes externally derived text before terminal output.
tui
update
Package update checks GitHub Releases for newer termp versions and selects the update command that matches the current installation.
Package update checks GitHub Releases for newer termp versions and selects the update command that matches the current installation.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL