AboutExperienceSkillsWork
SK
GuestbookBlogResumeContact
HomeWorkExp.BlogGuests
Cover
BlogsBack to Blogs
January 11, 2026, 12:25 AM6 min read

Never Lose Context Again: Building a Better Terminal History

I live in the terminal. Whether I'm building data pipelines or optimizing serverless functions, my command history is my second brain.

But the standard Zsh history (~/.zsh_history) has a major flaw: It lacks context.

Six months from now, when I find that complex ffmpeg or aws s3 command I ran, I won't remember:

  • Which directory I was in?
  • Which Git branch was active?
  • Which Conda environment was loaded?
  • Did the command actually succeed?
  • How long did it take?

I decided to solve this by building a Global Command History—a system that tracks everything. Here is how I built it.

The Problem with Default History

Standard shell history saves the command string. If you configure it well, you might get a timestamp. But that’s it.

bash
# Standard History 8923 git commit -m "fix bug" 8924 docker build . 8925 ./scripts/deploy.sh

This tells me nothing about the state of my machine when I ran those commands. If ./scripts/deploy.sh failed, I wouldn't know. If docker build took 45 minutes, I wouldn't know.

The Solution: Enriched Metadata

I wrote a lightweight Zsh plugin, cmdlog, that hooks into the shell's execution lifecycle to capture metadata before and after every command.

Instead of a simple list, my history looks like this:

text
[2026-01-09 14:30:01] /Users/sumit/dev/api [git:main] (conda:py311) -> npm install [2026-01-09 14:32:05] /Users/sumit/dev/api [git:main] (conda:py311) [2m4s] -> docker build . [2026-01-09 14:35:10] /Users/sumit/dev/api [git:feature-x] (conda:py311) [EXIT:1] -> ./test.sh

Screenshot 2026-01-11 002438.png

Now I have context:

  1. Directory: I know exactly where the command ran.
  2. Git Branch: I know I was on feature-x when the test failed.
  3. Environment: I know I was using Python 3.11.
  4. Duration: I know the build took 2 minutes and 4 seconds.
  5. Exit Code: I see immediately that ./test.sh failed (Exit 1).

Install in 3 Seconds (The Lazy Way)

I packaged this into a standalone tool so you don't have to copy-paste scripts. If you want this enhanced history in your terminal right now, just run:

bash
curl -fsSL https://raw.githubusercontent.com/smaxiso/cmdlog/main/install.sh | bash

(Always inspect scripts before piping them to bash! View the source here)

That's it. Restart your terminal, and you're tracking.

Under the Hood: The Code

The logic relies on two Zsh hooks: preexec (runs before a command starts) and precmd (runs after a command finishes). zsh_flow.jpg

1. Tracking Duration (preexec)

First, we capture the start time when a command begins.

bash
preexec() { CMD_START_TIME=$(date +%s) }

2. Logging the Context (precmd)

This is where the magic happens. We calculate the duration, capture the exit code of the previous command, and grab the environment details.

bash
log_global_command() { local exit_code=$? # Must be the very first line # ... (timestamp, directory, git branch logic) ... # Write to the global log file if [[ $exit_code -eq 0 ]]; then printf "[%s] %s [git:%s] %s -> %s\n" ... >> ~/.global_history else printf "[%s] %s [git:%s] [EXIT:%d] %s -> %s\n" ... >> ~/.global_history fi }

The Superpower: Querying Your Life

Collecting data is useless if you can't query it. I created a set of POWER aliases to turn this log file into a tactical weapon.

1. The "Rewind Button" (cmdlog [N])

Want to see what you just did?

  • cmdlog shows the last 20 commands.
  • cmdlog 100 shows the last 100.

No more scrolling up infinitely.

2. The "Debugger" (cmd-errors)

If I'm debugging a flaky build script, I can filter specifically for commands that failed.

bash
alias cmd-errors='grep "\[EXIT:" ~/.global_history'

3. The "Context Search" (cmd-here)

Standard history searches everything. Sometimes I only want to know what commands I've run in this specific folder.

bash
alias cmd-here='grep ":$(pwd)" ~/.global_history'

4. The "Standup Helper" (cmd-today)

Engineers hate trying to remember what they worked on yesterday. Just run cmd-today and see every command you ran since midnight.

Why You Should Do This

This setup has saved me countless hours. It allows me to:

  1. Audit my work: "Did I actually run the migration in prod or just staging?"
  2. Optimize builds: I can spot when my build times start creeping up because I track duration.
  3. Recover context: I can restore the exact environment (branch + conda env) needed to reproduce a bug from three weeks ago.

It's entirely portable. Whether I'm on my MacBook, WSL, or an EC2 instance, my history travels with me.

📦 Check out the Repo on GitHub

Topics
#Zsh#Productivity#Bash Scripting#Linux#Engineering#Workflow
Thanks for reading!
Share this post: