7 minutes
My Shell Setup: Terminal Configuration with Ghostty, zsh, and AI Powered Tools

Every developer has their terminal setup. Most stick with defaults. Some tweak colors and aliases. Few build something that changes how they work daily. After years of iteration, I’ve put together a shell configuration that handles multiple shells, integrates with modern terminals, and includes tools that save hours each week.
This setup works with both zsh and bash, runs smoothly in Ghostty terminal, and includes AI-powered command generation alongside traditional productivity tools. Let me walk you through what makes it work.
The Foundation: Ghostty, zsh, and bash
The configuration starts with Ghostty, a terminal emulator that focuses on performance and simplicity. Unlike older terminals, Ghostty handles modern escape sequences and shell integration without the overhead.
The setup supports both zsh and bash. macOS ships with zsh as the default, so that’s the primary shell. But the configuration detects which shell you’re using and adjusts automatically. This dual-shell support means the same config works whether you’re in a zsh session or need to drop into bash for compatibility.
# Zsh configuration (.zshrc)
if [[ -o interactive ]] && command -v starship &> /dev/null 2>&1 && [[ "$TERM" != "dumb" ]]; then
eval "$(starship init zsh)"
fi
The bash configuration checks which shell is active before loading shell-specific features. This prevents conflicts and ensures Ghostty’s bash integration only loads when actually running bash.
tmux: Terminal Multiplexing Done Right
tmux handles window management, session persistence, and multi-server workflows. The configuration uses screen-256color as the terminal type, which ensures proper color support and escape sequence handling.
Custom key bindings remove the need for the default prefix key in many cases. Press Ctrl+t to SSH to any host. Ctrl+e launches cluster SSH across multiple servers. Ctrl+g opens ShellGen for AI command generation. These shortcuts work without pressing the tmux prefix first.
The status bar shows session information, pane synchronization status, and AWS profile/region when configured. Windows and panes start at index 1 instead of 0, which matches mental models better.
# tmux key bindings (no prefix needed)
bind-key -n C-t command-prompt -p "SSH:" "new-window -n %1 'ssh %1'"
bind-key -n C-e command-prompt -p "Cluster SSH:" "new-window 'exec sh ~/clssh.sh %%'"
bind-key -n C-g command-prompt -p "ShellGen:" "split-window -v 'sh ~/shellgen.sh %%"
Starship Prompt: Information at a Glance
Starship provides the prompt. It shows username, hostname, directory, git status, AWS credentials, Python/Node versions, and battery status when relevant. The configuration uses a custom “Pastel Neo Tokyo” color palette for visual consistency.
Getting Starship to work in tmux required fixing a TERM variable issue. Starship disables itself if it detects TERM=dumb. The solution was setting TERM=screen-256color in .zshenv, which loads before .zshrc runs Starship initialization. This ensures Starship sees the correct terminal type and enables properly.
# .zshenv - fixes TERM before Starship checks it
if [ -n "$TMUX" ]; then
case "$TERM" in
screen*|xterm*|*256color*)
# Already good
;;
*)
export TERM="screen-256color"
;;
esac
fi
The prompt format shows: username:directory git_branch git_status ❯. Colors indicate status at a glance-yellow for git branches, red for uncommitted changes, green for clean repositories.
ShellGen: AI-Powered Command Generation
Here’s where the setup gets interesting. ShellGen uses Ollama (a local LLM) to generate shell commands from natural language. Instead of searching Stack Overflow or reading man pages, you describe what you want and get the exact command.
The function connects to Ollama running locally with the glm4:9b model. It takes your query, sends it to the LLM, and returns a command. The command gets added to history but doesn’t execute automatically-you review and run it yourself.
shellgen() {
set -f # disable globbing
local query="$*"
local prompt="You are a command line expert. User query: ${query}. Output ONLY the exact shell command..."
local cmd
cmd=$(curl -s http://localhost:11434/v1/chat/completions \
-H "Content-Type: application/json" \
-d "{\"model\": \"glm4:9b\", \"messages\": [{\"role\": \"user\", \"content\": \"$prompt\"}], \"stream\": false}" | \
jq -r '.choices[0].message.content' | \
sed -e 's/^```[a-z]*//' -e 's/```$//' -e 's/^`//' -e 's/`$//' | \
tr -d '\000-\037')
set +f
history -s "$cmd"
printf '\033[1;32m =❯ \033[0m%s\n\n' "$cmd"
}
Usage: shellgen "find all python files modified in the last week" returns find . -name "*.py" -mtime -7. The command appears in green, gets added to history, and waits for you to execute it.
This works because Ollama runs locally-no data leaves your machine. The glm4:9b model is small enough to run on most modern hardware while being accurate for shell command generation.
Cluster SSH Script: Managing Multiple Servers
The clssh.sh script handles simultaneous connections to multiple servers. It’s useful for running commands across development environments, deploying updates, or checking status on several machines at once.
The script requires tmux. When you run Ctrl+e and enter hostnames (or a predefined alias like docker-lab), it splits the tmux window into panes, one per host. Each pane SSHes to its server, and synchronize-panes turns on automatically. Type once, execute everywhere.
#!/bin/bash
# Cluster SSH Script
if [ "$1" = 'docker-lab' ]; then
HOSTS="control lb01 app01 app02 db01"
tmux rename-window "Docker Lab"
else
HOSTS=$*
tmux rename-window "Cluster"
fi
for i in $HOSTS
do
tmux splitw "ssh $i"
tmux select-layout tiled
done
tmux set-window-option synchronize-panes on
Predefined aliases like docker-lab connect to specific server groups. You can also pass hostnames directly: clssh.sh web01 web02 web03 connects to all three in a tiled layout.
Compatibility Fixes: Making It All Work Together
Getting Ghostty, tmux, zsh, and Starship to work together required solving a few compatibility issues. Ghostty’s shell integration sends escape sequences that appeared as raw text in tmux. The solution was detecting when running inside tmux and disabling Ghostty integration automatically.
The .zshenv file fixes the TERM variable early in the shell startup sequence. The .zshrc handles Starship initialization and Ghostty integration cleanup. The .bashrc checks which shell is active before loading shell-specific features.
This layered approach means each component initializes in the right order, with dependencies handled correctly. The result is a setup that works whether you start a new terminal, attach to tmux, or SSH into a remote system.
Configuration Files Overview
The setup includes separate configuration files for different purposes:
.zshenv: Environment variables, TERM fixes, PATH additions (loads first).zshrc: Interactive zsh configuration, Starship initialization.zprofile: Login shell setup, Homebrew, nvm loading.bashrc: Shared configuration, shellgen function, conditional Starship init.tmux.conf: tmux settings, key bindings, status bar configurationstarship.toml: Prompt format, colors, module configuration
Each file has a specific role, and the loading order ensures everything works together.
📦 View all configuration files on GitHub →
The latest files and updates are available in the dotfiles repository for easy setup on new systems.
Getting Started
Setting up this configuration on a new system takes about ten minutes:
- Copy configuration files to home directory
- Install Starship:
brew install starshipor use the official installer - Install Ollama and the glm4:9b model for ShellGen (optional but recommended)
- Reload shell configs and start tmux
The setup works on macOS out of the box. Linux users may need minor adjustments for paths and package managers, but the core concepts transfer directly.
Why This Setup Works
This configuration works because it addresses real workflow problems. Need to run a command but don’t remember the syntax? ShellGen helps. Managing multiple servers? Cluster SSH handles it. Want context about your environment at a glance? Starship shows it.
The dual-shell support means you’re not locked into one environment. The tmux integration keeps everything in one session. The Ghostty terminal provides the foundation for fast, reliable operation.
Most importantly, each piece solves a specific problem. Nothing is included because it’s trendy or looks cool-everything serves a purpose in daily work. After using this setup for months, it’s hard to imagine working without ShellGen’s command suggestions or the cluster SSH workflow.
The Bottom Line
A good shell setup should fade into the background while making work faster. This configuration achieves that by combining proven tools (tmux, zsh, bash) with modern additions (Ghostty, Starship) and custom solutions (ShellGen, cluster SSH).
The result is a terminal environment that handles multiple shells, provides visual feedback, and includes AI-powered assistance without requiring constant attention. It’s a setup built for daily use, not demonstration.
🔗 Get the latest configuration files on GitHub
All configuration files and documentation are available in the dotfiles repository. The setup continues evolving, but the core principles-compatibility, productivity, and simplicity-remain constant.