Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

roost

A tiny tmux project session manager. Every project gets its own named, persistent tmux session. Run roost <name> to drop into a project (creating its session if needed), or roost -s to boot all your common projects at once. Sessions survive closing the terminal; they only end on reboot or an explicit kill.

If you tend to drown in a dozen look-alike terminal windows, roost replaces them with one window and a handful of named sessions you switch between.

Why

  • One session per project. No more hunting through identical terminals.
  • Persistent. Close the terminal, come back later, everything is still there.
  • Startup groups. Boot your daily projects with a single roost -s.
  • Just tmux. No daemon, no runtime. A single Bash script and a text config.

Requirements

  • tmux (brew install tmux on macOS)
  • Bash 3.2+ (the macOS system Bash is fine) and zsh for tab-completion

Install

git clone https://github.com/<you>/roost.git ~/code/roost
cd ~/code/roost
./install.sh

install.sh symlinks bin/roost into ~/.local/bin and seeds ~/.config/roost/projects.conf from the example. It then prints the two lines to add to your ~/.zshrc (put ~/.local/bin on PATH and enable completion). Reload with source ~/.zshrc or open a new terminal.

Verify:

roost --list

Configure

Your projects live in ~/.config/roost/projects.conf, outside this repository. It is personal and never published: the repo ships only a generic projects.example.conf, and projects.conf is gitignored so your real project names and paths stay on your machine.

The file is one project per line, pipe-delimited:

name | path | flags | command
Field Meaning
name Session name and the argument to roost <name>
path Project directory (a leading ~ is expanded)
flags Comma-separated; startup includes it in roost -s
command Optional; run in the new session (an editor, agent, dev server)
display Optional label in roost --list; defaults to the folder name

Trailing fields are optional, so name | path alone works. Lines starting with # are comments; blank lines are ignored. Example:

web    | ~/code/web-app     | startup | npm run dev | Web App
api    | ~/code/api-service | startup |             | API
notes  | ~/notes            |         |             |

A project does not have to be listed. roost <name> also works for any directory at your root (default ~/code/<name>), so ad-hoc projects need no config entry.

Config directives

Optional @-directives at the top of the config set defaults, so you do not need environment variables for everyday settings. A matching environment variable still takes precedence over the directive.

@root ~/code         # base dir for unlisted projects (roost <name> -> <root>/<name>)
@default_cmd nvim    # command run in every new session
@main main           # name of the base session that plain `roost` attaches to

Setting precedence is: environment variable, then @-directive, then built-in default.

Usage

roost                 Attach to your base session (creates it if needed)
roost <name>          Create or re-attach a session for a project
roost -s, --startup   Start every 'startup' project, attach to the first
roost -l, --list      List configured projects and their session status
roost -h, --help      Show help

roost is smart about where you run it:

  • From a plain terminal, it attaches that terminal to the session.
  • From inside tmux, it switches your current client to the session (no nested-session mess).

Either way you never spawn a duplicate: an already-running session is reused.

Typical day

roost -s          # morning: boot web, api, and friends; land in the first
# ... work, Ctrl-a s to hop between them ...
roost notes       # jump to a project not in the startup group

Launch from Spotlight, Raycast, or Alfred

Spotlight only launches .app bundles, not shell commands. To make roost Spotlight-searchable, build a small wrapper app:

extras/make-launcher.sh        # app runs: roost
extras/make-launcher.sh -s     # app runs: roost -s  (boot startup projects)

It creates ~/Applications/Roost.app. Press Cmd+Space, type Roost, and hit Return to open Terminal straight into your sessions. Remove it with rm -rf ~/Applications/Roost.app.

Environment variables

Variable Default Purpose
ROOST_CONFIG ~/.config/roost/projects.conf Config file path
ROOST_ROOT ~/code Base dir for unlisted projects
ROOST_DEFAULT_CMD (none) Command run in every new session
ROOST_MAIN main Name of the base session
ROOST_NO_ATTACH 0 1 creates sessions but does not attach

ROOST_DEFAULT_CMD is handy if you always open the same tool in a project. For example, export ROOST_DEFAULT_CMD=nvim starts each session in your editor.

How it works

roost is a thin wrapper over standard tmux commands:

  • roost <name> runs tmux new-session -d (only if the session is not already running), optionally send-keys for the project command, then attach-session or switch-client depending on whether you are inside tmux.
  • roost -s repeats that for every project flagged startup.
  • The session name equals the project name, matched exactly, so names never collide by prefix.

Nothing runs in the background except tmux itself. Delete the script and your config and roost is gone; your tmux sessions are unaffected.

A one-minute tmux primer

roost gets you into a session; tmux keys move you around inside it. The default prefix is Ctrl-b (many people remap it to Ctrl-a). Press the prefix, release, then the next key.

Action Keys
Detach (leave it running) prefix then d
List / switch sessions prefix then s
New window (tab) prefix then c
Rename window prefix then ,
Next / previous window prefix then n / p
Split panes prefix then % / "

Reattach later from any terminal: tmux attach -t <name> (or just roost <name>).

Uninstall

rm -f ~/.local/bin/roost                 # remove the command
rm -rf ~/.config/roost                   # remove your config (optional)
rm -rf ~/Applications/Roost.app          # remove the launcher, if created
rm -rf ~/code/roost                      # remove the clone

Remove the roost block you added to ~/.zshrc as well.

Contributing

Issues and pull requests are welcome. roost aims to stay small: a single dependency-free Bash script that does one thing well. Please run shellcheck on bin/roost before submitting.

License

MIT (c) 2026 Corvalon.

About

A tiny tmux project session manager: one named, persistent session per project, with startup groups.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages