Skip to content

Terminal productivity: the tools that transformed my workflow

Chance Jiang
Published date:

The CLI ecosystem experienced a silent revolution. Tools written in Rust and Go replaced decades-old Unix binaries, adding colors, syntax highlighting, fuzzy search, and Git-awareness with almost no sacrifice in speed. These are the ones I use daily.

But this is only Act I. Act II is the real game-changer: layering AI-coding LLMs on top of this modern stack. The terminal is no longer just a place where you execute commands — it’s where you converse with code. This essay is a tour through both acts.

Table of contents

Open Table of contents

Shell: Zsh + Starship

Starship is undoubtedly the prompt that most improves the experience with the least effort. It works with any shell, is incredibly fast (written in Rust) and shows relevant context: Git branch, Node/Python/Rust version, last command status.

# Minimalist but informative style
format = """
$directory\
$git_branch\
$git_status\
$nodejs\
$rust\
$python\
$cmd_duration\
$line_break\
$character"""

[git_branch]
symbol = " "
style = "bold purple"

[git_status]
conflicted = "⚔️ "
ahead = "⇡${count}"
behind = "⇣${count}"
modified = "✎${count}"
untracked = "?${count}"

[cmd_duration]
min_time = 2_000
format = "took [$duration](bold yellow)"~/.config/starship.toml

Classic tool replacements

lseza (formerly exa)

eza --tree --level=2 --icons --git    # tree with icons and Git status
eza -la --sort=modified               # long list, sorted by date

findfd

# find: verbose and poor ergonomics
find . -name "*.ts" -not -path "*/node_modules/*"

# fd: intuitive, respects .gitignore by default
fd -e ts                    # all .ts in the project          
fd -e ts --exec bat {}      # open each result with bat       

grepripgrep (rg)

# classic grep
grep -r "useEffect" src/ --include="*.tsx"

# rg: 5-10× faster, respects .gitignore
rg "useEffect" --type ts
rg "TODO|FIXME|HACK" --type ts --stats
rg "deprecated" -l                               # filenames only 

catbat

bat is cat with syntax highlighting, line numbers, paging, and built-in Git diff:

bat src/components/Header.astro     # with colors and lines
bat --diff file.ts                  # shows inline Git changes

cdzoxide

It learns which directories you visit frequently and lets you jump to them with a few letters:

z astro      # jumps to ~/projects/my-astro-blog if it's the most visited
z blog src   # multiple match
zi           # interactive mode with fzf

Multiplexer: tmux with modern config

# More comfortable prefix
set -g prefix C-a
unbind C-b

# Split panes with intuitive keys
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"

# Navigation with Alt+arrow (no prefix)
bind -n M-Left  select-pane -L
bind -n M-Right select-pane -R
bind -n M-Up    select-pane -U
bind -n M-Down  select-pane -D

# Mouse enabled
set -g mouse on

# 256 colors
set -g default-terminal "tmux-256color"~/.tmux.conf

Fuzzy finder: fzf — the multiplier of everything

fzf turns any list into an interactive finder. Just add | fzf to any command.

# Search in command history
CTRL+R with integrated fzf

# Checkout branch with preview
git branch | fzf --preview 'git log --oneline {}' | xargs git checkout

# Kill processes
ps aux | fzf --multi | awk '{print $2}' | xargs kill

# Find and open file
fd -e ts | fzf --preview 'bat --color=always {}' | xargs nvim

Modern Git: lazygit

A Git TUI (Terminal UI) that makes it obvious what’s happening in your repository:

lazygit   # opens the interface

Standout features:


Turbo-charged: AI-coding LLMs on the terminal

Act I gave us a faster, friendlier shell. Act II makes it intelligent. The modern terminal’s real superpower is that every tool in this stack becomes an input pipe for an LLM.

git diff | llm — AI-powered commit messages

The single highest-ROI LLM trick for daily Git work:

# Generate a commit message from the staged diff
git diff --cached | llm "Write a concise conventional commit message"

Pair this with fzf to select from AI-generated suggestions, or pipe an entire branch diff for a PR summary:

# PR description from branch diff
git diff main...HEAD | llm "Write a pull request description as bullet points"

aider — AI pair programming in the terminal

Aider is the closest thing to having a senior engineer in your tmux pane. It watches your repo, reads your file tree, and makes surgical code changes directly:

aider --model deepseek-chat --architect

Standout features:

Typical workflow: describe what you want in natural language, review the diff, stage the changes you like. It’s like having fzf for code generation.

pi.dev — the hackable coding harness

Pi is the anti-framework: a minimal terminal coding harness that stays out of your way. Created by Mario Zechner (Earendil Inc.), it’s designed around a simple philosophy — adapt pi to your workflows, not the other way around.

# Install via npm
npm install -g @mariozechner/pi-coding-agent

Standout features:

Community vibe: Pi’s community feels like early Vim or Emacs — a mix of tinkerers and plugin authors sharing packages via npm and GitHub. The project’s monorepo (pi-mono) also ships a standalone LLM SDK (@mariozechner/pi-ai), a TUI library (@mariozechner/pi-tui), and web components, so the ecosystem extends well beyond the CLI itself. It’s not just a tool; it’s a platform for building your own agent.

A typical setup: install the base agent, drop in an extension for your framework, apply a community theme, and you’ve got a bespoke AI pair programmer that feels like your tool, not a product someone else designed.

CodeWhale — DeepSeek-native coding agent (formerly DeepSeek-TUI)

CodeWhale (rebranded from DeepSeek-TUI in v0.8.47) is a Rust-based terminal coding agent built specifically around the DeepSeek and MiMo model families. Where most coding agents treat Chinese-stack models as fallback providers, CodeWhale makes them first-class citizens — tuned for their tool-use and reasoning patterns.

codewhale    # opens the TUI

Design: a single-process, TUI-native loop written in Rust. No Electron, no heavy dependencies — just a terminal binary that talks directly to DeepSeek’s API or self-hosted MiMo endpoints. The interface feels like lazygit crossed with a chat client: diffs appear inline, file tree is navigable, and the model’s reasoning is streamed token by token into a side panel.

Community vibe: The CodeWhale community emerged from the Chinese open-source AI scene and has grown rapidly during the DeepSeek surge of early 2026. The project’s changelog reads like a real-time diary of the ecosystem — contributors include OpenWarp (who prioritized CodeWhale support in their terminal-agent UX tool) and various community members shipping multi-provider compatibility fixes. It’s a pragmatic, no-nonsense community that values low cost and high throughput. The rebrand from “DeepSeek-TUI” to “CodeWhale” signals ambition beyond a single model family, but the soul remains deeply tied to the DeepSeek + MiMo stack.

If your daily driver is DeepSeek or you self-host MiMo models, CodeWhale gives you a native TUI experience that’s faster and more deeply integrated than any generic agent.

The natural-language shell: sgpt / shell_gpt

ShellGPT (sgpt) turns your shell into a natural-language interface:

# Describe what you need
sgpt "find all large video files in this directory"
# -> outputs: find . -type f \( -name "*.mp4" -o -name "*.mov" \) -size +100M

# Fix the last command
sgpt --repl "explain why this failed and fix it"

I keep a dedicated tmux pane for an ongoing LLM conversation. It’s my man pages, my rubber duck, and my code generator all in one.

Piping the modern stack into an LLM

This is where Act I and Act II converge. Every modern CLI tool feeds naturally into an LLM:

# Debug with full context
rg "panic" --context 5 | llm "Explain what's causing this crash" | bat -l md

# Bulk refactoring
fd -e ts -x sh -c 'llm "Rewrite this to use async/await" < "$1"' _ {} \;

# Summarize logs with preview
journalctl -u my-service --no-pager -n 200 | llm "Summarize errors and suggest fixes"

# Code review with fzf + bat + llm
fd -e tsx | fzf --preview 'bat --color=always {}' \
  | xargs -I{} sh -c 'cat {} | llm "Review this code for bugs and DX issues"'

thefuck — the original AI-for-shell

Before LLMs were mainstream, thefuck corrected mistyped commands:

% apt-get install vim
# E: Could not open lock file

% fuck
# -> sudo apt-get install vim  [enter/↑/↓/tab]

It’s a small thing, but over a day it saves dozens of micro-frustrations. Modern LLM shells (sgpt, codewhale CLI) do this at a higher level by understanding intent, not just correcting typos.

AI as a tmux pane

My daily tmux layout has three panes:

┌──────────────────┬──────────────┐
│   Editor (nvim)  │  LLM Chat    │
│                  │  (codewhale /│
│                  │   sgpt)      │
├──────────────────┴──────────────┤
│   Terminal + lazygit            │
└─────────────────────────────────┘

The LLM pane stays open for quick questions, code reviews, and scaffolding. I never context-switch to a browser for API docs or Stack Overflow — the answer is one Alt+→ away.

.codewhale/specs/ — prompt-driven development

My latest workflow: write a spec in Markdown and let the LLM implement it:

  1. Write a spec file at .codewhale/specs/feature.md describing what to build
  2. Run codewhale --spec .codewhale/specs/feature.md — the LLM reads the repo, plans the changes, and implements them
  3. Review the diff with lazygit, tweak, and commit

This turns the terminal into a spec-to-shipped-code pipeline.

My optimized basic .zshrc

# Fast load with lazy loading
export PATH="$HOME/.cargo/bin:$HOME/.local/bin:$PATH"

# Modern aliases
alias ls='eza --icons'
alias ll='eza -la --icons --git'
alias tree='eza --tree --icons'
alias cat='bat'
alias find='fd'
alias grep='rg'
alias lg='lazygit'

# fzf integration
source <(fzf --zsh)

# zoxide
eval "$(zoxide init zsh)"

# starship
eval "$(starship init zsh)"

# AI helpers
alias pr-desc='git diff main...HEAD | llm "Write a PR description"'
alias commit-msg='git diff --cached | llm "Write a concise conventional commit message"'
alias explain='sgpt "Explain the following command or error"'~/.zshrc

The best time investment in terminal productivity is not learning new tools — it’s mastering the ones you already have. But when a modern tool does the same thing 5× faster with better DX, the switch pays for itself in the first week. And when you layer an AI-coding LLM on top? The terminal stops being a tool you operate and becomes a partner you collaborate with.


What’s next? Ideas to explore

This article only scratches the surface. Here are some directions worth diving deeper into:

Previous
Vibe Coding: programming with AI at the speed of thought