cckeep logo

Your session is still running.
Your phone doesn't know.

Claude Code 2.1.232 fixed the 31-second give-up. What it left behind: the disconnects that still end with you walking back to your desk to type /remote-control. cckeep notices, and re-arms the session — without ever typing into one that's busy.

$npm i -g cckeep && cckeep enable

Zero dependencies · zero cloud · zero telemetry — it reads your tmux panes and nothing leaves the machine.

cckeep detecting a dead Remote Control link and re-arming it

What Claude Code still leaves to you.

Remote Control now reconnects for about 30 minutes on its own, and an interactive session retries for as long as an outage lasts — the failure this tool was built for is fixed. These are the ones that still end with the link closed and you walking back to your desk to type /remote-control.

💓The heartbeat

The link stays up while the session's heartbeats don't. Claude Code re-registers for about 30 minutes, then disconnects — and the documented recovery is to run /remote-control.

🚫The 403

A VPN or network change puts something in the path that answers 403. Claude Code tolerates it for three minutes, then disconnects and names what refused. Nothing brings it back.

🪢The wedge

Sometimes it just sits in “reconnecting” — issue #34255, open since March, 99 👍. Whether it still reproduces against the reconnect path 2.1.232 reworked is unconfirmed.

It will not type into a session that's working.

A watchdog that types into your terminal on a timer is a liability unless it's certain the moment is safe. Every rule below is enforced and tested.

⏸️
Never during a turn

The pane is captured three times, on an interval that is deliberately not round — an animation whose period divided it would alias into identical frames. A running turn animates a spinner and a token counter, so identical captures mean nothing is happening, different ones mean hands off.

🚧
Never into a dialog

Permission prompts turn Enter into a selection. If a selection marker is on screen, the pass is skipped entirely.

📱
Never into your panel

/remote-control opens a status panel with a QR code. cckeep presses Enter there only when it opened the panel itself.

🔕
Never a session you turned off

Only panes seen connected at least once are ever chased. Disable Remote Control deliberately and it stays off.

🧊
Never in a tight loop

One action per pane per five minutes, so a genuinely broken link can't turn into a stream of keystrokes.

🔁
Re-checked at the last moment

The decision is made from one capture, then re-verified after the wait. Reconnected in between? Dialog appeared? Nothing is sent.

--dry-run prints exactly what it would do and sends nothing. Run it for a day before you trust it.

What it watches for.

State on screenWhat it meansWhat cckeep does
/rc activeconnectedremembers the pane, nothing else
/rc reconnectingClaude Code is reconnecting, with about 30 minutes to do itwaits — this is the case 2.1.232 made reliable
/rc reconnecting · 35 minpast Claude Code's own window: wedged (#34255), or an outage still runningcycles the bridge: opens the panel, disconnects, reconnects
Remote Control disconnectedgave upre-arms immediately
no indicator, pane had one beforenotification scrolled awayre-arms after 4 quiet checks
no indicator, pane never had onenot your setupnothing, ever

One command away.

npm i -g cckeep       # install globally — an npx path would vanish
cckeep enable        # launchd on macOS, systemd user timer on Linux
cckeep               # what it sees right now — changes nothing
cckeep watch         # run in the foreground instead of scheduling
cckeep doctor        # tmux, panes, scheduler, paths
cckeep logs          # what it has done
cckeep disable       # remove the background job
One requirement: Claude Code has to run inside tmux.

A session started in a bare terminal can't be reached from another process — there's no channel to type into, so no tool can help it. Restarting the process isn't an alternative: that ends the conversation, which is the thing you were trying to save.

The README has a drop-in shell function that wraps interactive launches only, so claude update and claude -p keep behaving normally.

The best outcome is that this becomes unnecessary.

cckeep re-arms a connection. Claude Code 2.1.232 already removed the biggest reason it existed, which is exactly the right direction. If #34255 gets fixed too, the right move is to archive this repo. Until then, a 👍 over there is worth more than a ⭐ here.

Star history

Star history chart