By Aram Melkoumov, CEO of Crowdlinker
I run seven Claude Code sessions at once. One handles outbound email, one drafts legal documents, a few belong to landing pages and ad campaigns. Some have been open for four weeks and carry everything we decided along the way.
Then macOS installed an update and restarted. I lost everything I had running in my tabs and spaces: every pane came back as an empty shell.
Getting those sessions back was slow and frustrating. The hard part was keeping track of which session id belonged to which piece of work, and once I had them back I could not see most of what had been said in them. This post is what I built afterwards so it takes one command, and what I would tell anyone setting up the same thing. The scripts, the cheat sheet and the agent files are open source: herdr-claude-kit on GitHub.
I use Herdr to hold the sessions. It keeps coding agents in terminals that stay alive when you close the window, and it organises them the way I think about the work:
Each session is long-lived on purpose. When I come back to a campaign a week later, the session already knows the list rules, the copy we rejected and why.
Herdr is clear about this on its own site: after a reboot, a logout or a stopped core, each pane comes back as a shell in the folder it was in, and Herdr does not restart the agent. So the layout survives and the conversations do not.
| Event | Spaces and tabs | Claude sessions | What you do |
|---|---|---|---|
| Close the window, or update the app | Stay | Keep running | Nothing |
hc server restart | Stay | Keep running | Nothing |
hc server stop, then hc server start | Stay | Closed, each tab gets a shell | Run the restore command |
| Reboot, OS update, logout | Come back | Closed, each tab gets a shell | Run the restore command |
Two things made recovery painful.
First, and this was the big one, I had no way to keep track of session ids. Each session is identified by a long random id, and I had started all seven from my home folder. claude --continue reopens the most recent session in the current folder, so it could only ever find one of them. For the rest I was reading session ids out of transcript files and guessing which belonged in which tab.
Second, a resumed session only shows part of its history. Long sessions get compacted: Claude replaces the older conversation with a summary to free up room. When you resume, the screen starts at the last compaction. One of my sessions had been compacted seven times. The decisions I wanted to re-read were on disk, in a 258 MB transcript file, with no way to read them.
One note before you copy anything: Herdr's terminal version documents a built-in option that resumes agents after a restore. I could not find it in the product I run (the Herdr app 0.1.15 on herdr-core 0.1.20). As far as I can tell that gap is still open in the app, which is why I built this and why I am writing it up. Check your version first. You may not need the scripts.
Together they are about 720 lines of shell and Python. None of it is specific to Herdr in principle. If you use tmux or something else, the same three pieces apply; only the "which pane am I in" and "type this into that pane" calls change.
1. A hook that remembers which session lives in which tab. Claude Code runs hooks when a session starts and ends, and passes them the session id and transcript path. Mine writes one small record per Herdr terminal: the terminal, its tab, the session id and the folder Claude was started in. When I quit a session on purpose, the hook deletes the record. When the session dies any other way (reboot, crash, closed pane), the record stays.
2. A restore command. claude-restore reads the records. For each one it checks that the terminal still exists, still belongs to the same tab and is sitting at an idle shell prompt. Then it types claude --resume <session id> into that tab, one tab per second. Sessions that are already running are skipped.
3. A history viewer. claude-history turns a session's transcript into a searchable page in the browser, including everything from before each compaction. This is the one I use most. "What did we decide about pricing three weeks ago" is now a search.
I keep this as a file and look at it more often than I would like to admit.
| Situation | Command |
|---|---|
| After a reboot or OS update | claude-restore |
| See what it would do first | claude-restore -n |
| List which session is recorded for each tab | claude-restore -l |
| Bring every session back on your current default model | claude-restore --default-model |
| Restart Herdr's core without closing anything | hc server restart |
| Read a session's full history | claude-history t6 (a tab), or ! claude-history from inside the chat |
| Search every session for a phrase | claude-history -s "some phrase" |
| Name a session so you can find it later | /rename Short name |
| Finish with a session for good | /exit (this also stops it coming back after the next reboot) |
These are the parts I would have paid to know in advance.
I asked a Claude session to stop Herdr, start it and restore everything. It worked, and every session came back. Then I noticed a small warning in the status line: transcript saving was off. About 25 minutes of conversation across the seven tabs was never written to disk. The cause is documented. Claude Code marks anything it launches as a child session, and child sessions are left out of resume and history. The restarted server inherited the marker and passed it to every new shell. Run restarts yourself, from a plain terminal. The restore script now strips the marker as well.
I changed my default model and restored. All seven sessions came back on the old one. That is the documented behaviour: resume restores the model the session was using unless you pass --model. Hence the --default-model flag.
Claude Code's advisor is an experimental feature: a second model that reviews the conversation at key moments. It has to rank at or above the main model. My existing sessions had started with an older advisor, so when I moved them to a stronger main model they simply had none. What brought it back in my sessions was running /compact in each tab. New sessions were not affected.
While testing, I ran the restore from one Herdr tab against another. It printed "ok" and nothing had started. The command had arrived wrapped in an <hc> tag, the shell rejected it as a parse error, and the send still reported success. I only caught it because I looked at the target tab. Now I check what actually landed there.
I thought the scripts were done after they worked once. An independent reviewer, a separate agent that sees only the change and the requirement, found 14 defects. Three more rounds each found a few more.
One session had grown to 258 MB, so we wrote a handoff note and started a new one. The new session opened at almost the same context size, most likely because the tools and skills load into every session. It did give us a 1.4 MB transcript and a handoff note that corrected two things the old session had wrong.
The same week I rebuilt how the sessions divide their work. Each role has its own model and effort level, defined as a small file in ~/.claude/agents/ (subagents in Claude Code's terms).
| Role | Model | Effort | Job |
|---|---|---|---|
| Main session | Fable 5.2, 1M context | high | Plans, decides, does most of the work |
| Advisor | Fable 5.2 | high | Reads the whole conversation before big plans, before anything outward-facing and before "done" |
| Worker | Opus | high | Carries out a decided plan; never sends or publishes unless told to |
| Reviewer | Opus | xhigh | Checks code before it is called done; reports problems, never edits |
| Researcher | Sonnet | high | Web and docs lookups, with sources |
| Explorer | Sonnet | high | Read-only file and code search |
Three choices sit behind that table.
The reviewer runs on a different model from the one that wrote the code. A model reviewing its own work shares its own blind spots. The reviewer is handed the change and the requirement, and is not told what the author thinks of the change.
The rules for when to use each one are written down. A short CLAUDE.md tells the main session when to consult the advisor (before a large plan, when the same error repeats, before declaring a long task done, before anything that sends or publishes) and which agent to hand each kind of task to. One rule earned its place this week: after a compaction, re-read the live record before acting on anything remembered. That rule is how we found out that a campaign an old session's notes still described as live had finished days earlier.
Sends and launches always ask first. Claude Code permission rules have an ask list, and those rules prompt in every permission mode. Ours covers the tools that send email, post messages, activate campaigns or switch ads on. An agent can prepare all of it. A person presses the button.
~/.local/bin and make them executable. They need jq and Python 3.~/.claude/settings.json.claude-restore -l should list every tab.hc server stop; hc server start; sleep 3; claude-restore.~/.claude/agents/ and adapt the CLAUDE.md rules to your own work.
At Crowdlinker, agents do a large share of the delivery work, on client products and in our own operations. That only holds up if the sessions doing the work are treated like any other part of the system: they keep their history, they can be recovered, and someone other than the author checks what they produce. The whole thing is a hook, two scripts and a page of rules. It took losing my sessions once to convince me it was worth writing.
