May 23, 2026blog

Restarting Foreground Jobs Without Touching the Terminal

A small zsh plugin so agents (and other terminals) can bounce long-running commands.

You’re working with an agent in one terminal while a dev server runs in another. Sooner or later, the agent needs to restart the server, but has no idea how you started it, which terminal it’s in, or what its PID is. So all progress grinds to a halt until you notice that its asked you to do something trivial.

zsh-reap is a tiny zsh plugin that fixes this. Foreground jobs running for at least five seconds are watched, killable, and restartable from any other terminal (including an agent’s Bash tool) like this:

$ zsh-reap list
ID         PID     SHELL   CWD                  UPTIME   COMMAND
1319a-8e   78234   ttys003 ~/work/myapp         0:14:22  npm run dev
138f0-1f   80112   ttys005 ~/work/myapp/api     0:02:11  cargo run --release

$ zsh-reap restart 1319a-8e

The restart lands in the original shell — same $PATH, same $VIRTUAL_ENV, same nvm version, same everything. From the user’s point of view the terminal looks exactly as if they’d hit Ctrl-C and re-typed the line.

Tightly scoped

I built this for a single specific scenario: long-running foreground jobs to kill and restart. A few decisions worth flagging:

  • Restart only works in the originating shell. The restart runs inside the same live shell as the original invocation and inherits env vars, history, sockets, etc. for free.
  • Restarts run the whole command string. No changes, nothing else. If you need those, your agent can kill the job and run it again.
  • Foreground only. Background jobs (&) are already handled by jobs/fg; users have a mental model for those.
  • Minimal dependencies zsh, ps, pgrep, kill. No jq, no Python.

How does it work?

I’m not sure myself. Your agent could read the spec that my agent wrote up and explain it to you better than I could.

Why this matters

This isn’t a flagship tool. It’s a microscopic zsh plugin that solves one specific friction. The interface is zsh-reap list/restart, and it works the same way from a tmux pane, a script, or a Claude Code Bash tool call.

The shape of the solution is worth repeating: small agent-friendly tools that ease small and specific problems in human-agent collaboration. (jqi, which I wrote up earlier this year, is the same instinct applied to JSON exploration — different problem, same tiny shape.)

I’m betting (along with a large part of the ecosystem) that a large part of the savings that AI delivers is going to come from the proliferation of tools like these.