(
April 22, 2026
)

Resuming Agents Across Sleep and Wake: Why Our Own IDs Weren't Enough

Resuming an AI coding agent after sleep or a restart isn't a UI toggle — it's a data-plumbing problem multiplied by every CLI Influxx supports side by side.
Resuming Agents Across Sleep and Wake: Why Our Own IDs Weren't Enough
Resuming Agents Across Sleep and Wake: Why Our Own IDs Weren't Enough
Resuming an AI coding agent after sleep or a restart isn't a UI toggle — it's a data-plumbing problem multiplied by every CLI Influxx supports side by side.

"Put an agent to sleep and wake it up later with full context intact" sounds like a UI feature — a sleep icon, a resume button, done. It isn't. The moment a laptop lid closes, or Influxx itself idles a session to save resources, resuming that agent correctly stops being a UI problem and becomes a data-plumbing problem: each of the 30-plus agent CLIs Influxx supports has invented its own notion of what a "conversation" is and its own way to resume one, and none of those conventions are interchangeable. Getting this right meant admitting that Influxx's own internal identifiers were never going to be enough — and, at one point, finding that a piece of our own plumbing was quietly throwing away the one ID the whole feature depended on.

The Feature That Sounds Simple Until You Build It

Every laptop sleeps. Every agent CLI running inside Influxx keeps working right up until the operating system suspends the machine, or until Influxx itself decides an idle session isn't worth the memory and CPU it's holding onto and puts it to rest instead. Either way, the terminal tab is still sitting there when the machine wakes up, looking exactly like it did before. That's the trap. Reopening the tab and restarting the underlying process isn't resuming anything — it's starting a new, empty conversation that happens to be drawn in the same pane, with none of the history, none of the file context, and none of the multi-step plan the agent had been executing five minutes before the lid closed.

Resuming correctly means something much more specific: telling that exact agent CLI, using that CLI's own resume command, to reopen that exact prior conversation. Get the command or the identifier wrong and you don't get an error — you get a fresh session that looks plausible enough that a developer might not notice the context is gone until the agent asks a question it should already know the answer to.

Every Agent CLI Invented Its Own Notion of a "Conversation"

This is where a single-CLI tool would have an easy time, and Influxx doesn't. If you only ever launched one agent, you'd learn its one resume convention, hard-code it, and move on. Influxx runs Claude Code, Codex, Cursor, GitHub Copilot, Gemini, Grok, Droid, Amp, OpenCode, and more than thirty CLIs in total, side by side, each in its own isolated git worktree — and every one of them shipped its own answer to "what is a session, and how do you get back into one."

  • Claude Code: resumes a specific conversation through its own resume flag, paired with that conversation's own session identifier — a format Claude Code defines and controls.
  • Codex: has an equivalent resume mechanism, built around its own identifier format, generated and understood only by Codex.
  • The rest of the roster: Cursor, Gemini, Grok, GitHub Copilot, Droid, Amp, OpenCode, and the other supported CLIs each define a similarly-shaped but not identical convention — their own flag, their own identifier format, their own rules for what counts as a resumable session.

None of these are interchangeable. You cannot take the session identifier Claude Code generated and hand it to Codex's resume command, or the reverse, any more than you could use one country's passport number to satisfy a system built around a different country's ID scheme. Each CLI's resume path only accepts its own kind of identifier, in its own format, meaning what it means only to that CLI.

The Insight: Our Own IDs Are the Wrong IDs

The instinct, the first time you sit down to design this, is to reach for the identifiers you already have lying around. Influxx already tracks a tab ID for every terminal tab, a worktree ID for every isolated git checkout, a pane ID for every split. Surely one of those can stand in for "which conversation is this."

It can't, and that's the part that took real discipline to internalize. Those identifiers describe Influxx's own bookkeeping — which UI element, which checkout, which pane. The agent CLI running inside that pane has no idea any of them exist. It was never told about them, was never designed to accept them, and never will be, because they're not its concern. The only identifier that means anything to Claude Code, when you ask it to resume, is the identifier Claude Code itself generated for that conversation. The same is true, with a different format, for every other supported CLI.

So the job isn't "generate a good ID." It's "capture somebody else's ID, faithfully, for each of the thirty-plus somebody-elses, and hand it back to exactly the right one later." That reframes the whole feature: less UI, more supply chain.

Trusting the Binary Over the Documentation

Once you accept that every CLI's own provider-native session ID is the thing that matters, the next question is: what, exactly, does each CLI expect? Vendor documentation is a reasonable starting point, but it isn't something you can build a resume pipeline on faith alone — docs go stale, flags get renamed, edge cases go unmentioned, and a feature that only fails silently is exactly the kind of feature you don't want to discover is broken from a support ticket instead of from your own testing.

So the team ran a dedicated research pass that treated documentation as a starting hypothesis rather than a source of truth, and went straight to the installed binaries instead. For every supported CLI, on a real machine, we launched a session, captured what that CLI actually emitted as its session identifier, put it to sleep, and issued that CLI's own resume command with that exact identifier to confirm it actually reopened the same conversation with history intact. Where real behavior matched the documentation, that was confirmation. Where it didn't — a slightly different flag shape, an identifier format that wasn't quite what the documentation implied — the real behavior was what we built against.

"We don't get to assume a vendor's documentation matches what the binary on disk actually does. We install the real CLI, put a session to sleep, wake it up, and watch what comes back. That's the only definition of 'verified' we trust enough to ship."

— Priya Anand, VP of Engineering at ETAPX

The Gap We Found: Discarding the One ID That Mattered

That same research pass turned up something less comfortable. At the time, the internal pipeline responsible for normalizing lifecycle events from each agent CLI — the step that takes every CLI's own idiosyncratic output and turns it into one consistent internal shape Influxx can reason about — was silently discarding the provider-native session ID before sleep state was ever persisted. The identifier would arrive from the CLI, pass through normalization, and come out the other side without the one field the resume feature actually depended on. By the time a session was written down as "sleeping," the identifier needed to wake it back up correctly was already gone.

The practical effect: a session put to sleep under that specific condition couldn't be resumed with full context, because the information required to do so had already been thrown away before it was ever saved. Not corrupted, not misformatted — just absent, because an internal processing step had been treating it as disposable.

This wasn't a case of the feature going untested. It was a distinct, previously unverified condition, clearly separate from the paths that already worked correctly, and the team treated finding it as the entire point of this kind of verification — not as a failure of it.

"The honest version of this story is that our own normalization step was throwing away the one identifier the whole feature depended on, before we ever wrote sleep state to disk. Nobody put it there on purpose — it's exactly the kind of thing you only catch by testing the real path end to end, and exactly why we test the real path end to end."

— Daniel Kwon, Staff Engineer, Agent Orchestration at ETAPX

A Humbling Kind of Bug

It's a useful example of a failure mode common to systems with a lot of moving parts: nobody deleted the session ID on purpose, and nobody was thinking about sleep and resume when that code path was first written. A step built to make dozens of CLIs look consistent internally quietly dropped a field that turned out to be load-bearing for a feature built on top of it later. The fix wasn't clever — the field just needed to survive normalization instead of being treated as incidental. Finding it required exercising the real path end to end, rather than trusting that working pieces added up to a working whole.

What Changed, and Why This Stays a Moving Target

Fixing that one gap wasn't the same as declaring the problem solved, because the problem was never really "fix a bug." It's "keep faithfully capturing and reissuing the correct identifier for every CLI Influxx supports, including the ones we haven't added yet." A few things changed in how the team approaches that:

  • Capture at the source: the provider-native session ID is read directly from each CLI's own lifecycle output as early as possible, before it passes through any internal processing that could drop or reshape it.
  • Preserve through normalization: the hook-normalization pipeline now treats that identifier as a field that must survive, not one it's free to discard while reshaping everything else into a consistent internal format.
  • Verify against the real binary, every time: adding or updating support for a CLI now includes actually watching a full sleep-and-resume cycle succeed against the installed binary, not just confirming the code compiles against a documented interface.

That last point is the one that doesn't end. Influxx's whole premise is refusing to bet on a single agent CLI — running Claude Code and Codex and Cursor and dozens of others side by side, rather than picking a favorite and optimizing only for it. Every new CLI added to that roster brings its own resume convention, verified the same rigorous way, and any existing CLI can change its own convention in a future release. Sleep and resume isn't a feature you finish once. It's a contract Influxx keeps re-earning with every CLI it decides to support.

"I run long overnight refactors across three different agents and close the lid without thinking about it anymore. Six months ago I would have double-checked which sessions actually survived before trusting the results. Now I just open the laptop back up and keep going."

— Sam Rivera, founder of a three-person devtools consultancy

Frequently Asked Questions

What actually happens when my laptop goes to sleep in the middle of an agent session?

The agent CLI's process is suspended along with the rest of the machine. Influxx doesn't need to do anything special for the OS-level sleep itself — the important work happens on wake, when Influxx checks whether that session's underlying process is still alive and, if it isn't, resumes it using that specific CLI's own resume command and the session identifier that CLI issued when the conversation started.

Why can't Influxx just restart the CLI process instead of resuming it?

Restarting starts a brand-new, empty conversation in the same pane. It looks like the same session because the tab, the title, and the working directory haven't changed, but the agent has no memory of anything that happened before the restart. Resuming is a deliberate, separate operation: it hands the CLI its own prior session identifier so the CLI itself reloads the history, rather than starting over and hoping nobody notices.

Does every agent CLI Influxx supports handle resume the same way?

No, and that's the core difficulty. Claude Code, Codex, and every other supported CLI each define their own resume flag and their own session identifier format. Influxx has to know which convention applies to which CLI and use the right one — a Claude Code session identifier means nothing to Codex's resume command, and the reverse is equally true.

Where does the session identifier Influxx uses for resume actually come from?

From the agent CLI itself, not from Influxx. Influxx's own tab, worktree, and pane identifiers describe its own interface and git bookkeeping; they mean nothing to the CLI. The identifier that matters is the one the CLI generates for its own conversation, which Influxx captures from that CLI's lifecycle output, stores alongside the session, and hands back to that same CLI's resume command later.

When Influxx adds support for a new agent CLI, does resume have to be rebuilt from scratch?

Every new CLI does mean new work, because every CLI defines its own resume convention. Before support ships, the team verifies actual resume behavior against the real installed binary rather than trusting documentation alone — the same discipline applied to every existing CLI's resume path.

How did the team find the gap where session IDs were being discarded before sleep state was saved?

Through that same verification process. Testing sleep and resume against real installed CLIs, rather than only against expected behavior, surfaced a case where the internal pipeline that normalizes lifecycle events from each CLI was dropping the provider-native session ID before it was ever persisted. It was a distinct condition from the paths that already worked, and it became a priority fix specifically because it undermined this exact feature.

Resume across sleep looks, from the outside, like a small convenience — a session that picks up where it left off instead of starting cold. From the inside, it's a running commitment to track thirty-plus vendors' different definitions of a conversation, faithfully, without ever assuming Influxx's own bookkeeping can substitute for theirs. That commitment is exactly why we build against real, installed CLIs instead of their documentation, and exactly why finding a gap in our own plumbing changed how we verify this feature going forward, not just whether it happened to work today.