claude-rc-revive
Turn Claude Code's Remote Control back on after the claude.ai account changes.
A Remote Control (RC) session belongs to the claude.ai account that started it. When the machine's login moves to
another account (an account switcher such as cswap, or /login),
Claude Code stops RC in every session that has it:
signed-in claude.ai account or organization changed on this machine — run /remote-control to start a session for the current account
Nothing starts it again, so you have to type /remote-control in each session. claude-rc-revive does that for you.
Its command, rc-revive, watches the sessions, and in each one that lost RC to a switch it types
/remote-control <session name> into the session's tmux pane. That starts RC under the new account, titled with the
session's name.
Experimental. It reads Claude Code's screen and session files, which a new Claude Code version can change; it then waits or fails, logged, rather than typing blind. Tested with Claude Code 2.1.308 and 2.1.310. Not affiliated with Anthropic.
Install
Linux with systemd, tmux, Python 3.10 or newer, and Claude Code sessions running in tmux.
uv tool install claude-rc-revive # or: pipx install claude-rc-revive
rc-revive install-service # a systemd user service that runs `rc-revive watch`
To install from GitHub instead: uv tool install git+https://github.com/cskiraly/claude-rc-revive.
The service runs while you're logged in. To keep it running without a login session (as tmux sessions often do),
enable lingering once: sudo loginctl enable-linger $USER. After upgrading rc-revive, run rc-revive install-service
again: the running service keeps the old code until then.
How it works
Every 5 seconds it reads Claude Code's own session records (~/.claude/sessions/<pid>.json), which say whether RC
is on and name the session's tmux pane.
RC lost to a switch: RC went off in a session, and 10 seconds later the transcript doesn't show it was turned
off by hand (Claude Code writes a disconnect entry then; a switch doesn't). And either the machine's account
(oauthAccount in ~/.claude.json) changed while RC was on, or the session's last RC ran as another account than
the current one: a session can notice a switch late. RC that you turn off yourself stays off.
Typing, only when it's safe:
- the pane shows Claude Code's input box: no dialog, menu, permission prompt or question waiting, no tmux copy
mode, and the window's panes aren't synchronized (
synchronize-paneswould send the keys to every pane); - nobody pressed a key in that tmux session for 15 seconds;
- a draft on the input line goes to Claude Code's stash first (Ctrl+S), and comes back by itself after the command.
A suggested prompt (dim text) needs nothing: typing replaces it. It leaves a draft alone, and waits, when an older
stash is next to it (a second stash would overwrite the first); when the draft has a command or file menu open
(
/…,@…), which hides the stash; and when the session's Claude Code version is one it wasn't checked against for how the stash shows (2.1.308 and later 2.1 releases are). If the draft goes to the stash but the stash doesn't show, it pops the draft back and stops; - with vim keys (
/vim), only in INSERT mode and with an empty input line: NORMAL mode doesn't show, and there the typed text would run as commands.
It presses Enter only when the input line reads exactly what it typed, after a last look that nobody typed meanwhile and that RC didn't come on by itself. Then it checks the session record for a new RC session and that the draft came back. While it isn't safe it tries again every 5 seconds; it gives up 6 hours after the switch, counted from when the session stopped waiting for an answer. On anything unexpected it stops, takes back what it typed, and logs the screen.
Why the name: after a switch, Claude Code carries nothing of the conversation over to the new account, so a bare
/remote-control gets a title like <hostname>-<adjective>-<noun> in the Claude app. A name typed with the command
is used as the title. When the session's name has characters the input box could take for something else (only
letters, digits, space, ., _ and - are typed), or doesn't fit on the line, it types the command alone.
Usage
rc-revive watch every 5 s, revive the sessions that lost RC to a switch (what the service runs)
rc-revive status the sessions, their RC state and the account their last RC ran as
rc-revive revive TARGET... revive now: a pid, tmux pane (%N), tmux session name, or "lost" (every
session whose last RC ran as an account other than the current one)
rc-revive screen PANE how the input box of a pane reads (for testing)
rc-revive install-service run `watch` as a systemd user service, now and after every login
rc-revive uninstall-service stop that service and remove it
The log is ~/.local/state/rc-revive/log ($XDG_STATE_HOME/rc-revive/log), one JSON line per event, in local
time: start, switch (with the accounts' emails), rc-on, rc-off, lost-to-switch, left-off, wait, ok,
failed, give-up and error. It's also in the journal (journalctl --user -u rc-revive). The screen of every
failure goes to ~/.local/state/rc-revive/screens/. revive exits with 1 unless every session it was given got RC
back.
Caveats
- Only sessions in tmux, and only those using the default config directory (
~/.claude). - A session that is waiting on a permission prompt or a question gets RC back only after you answer it there,
since until then its input box isn't showing. A session it gave up on can be revived by hand:
rc-revive revive <pid or tmux session>. - If you type into a session in the second it takes, your keys and its keys mix. The 15-second quiet check makes that unlikely.
- In a session with an empty input line and a draft of yours in the stash, Claude Code puts that draft back on the input line after the command ("Draft restored"), as it does after any prompt you send.
- RC that goes off for another reason within a minute after a switch also gets revived.
The real fix belongs in Claude Code: after an account change, start RC again for the new account when it was on.
Tests
uv run pytest: the screen reader on panes captured from Claude Code (empty, suggestion, busy, permission prompt, a stash, the slash menu) and variants of them; the transcript reader; what it types, and when it waits, on a fake tmux pane; the service file; the watcher over time with stubs. Nothing is typed.tests/live-test.sh: on a throwaway Claude Code session in its own tmux session, a draft goes to the stash, RC comes on titled with the session's name, and the draft comes back; a draft plus an older stash is refused. It starts and disconnects two RC sessions under your current account (they show up in the Claude app for a moment), and sends no prompt to the model. Run it from a directory Claude Code already trusts;CLAUDE=<binary>tests another Claude Code version. It needsjq.
Uninstall
rc-revive uninstall-service
uv tool uninstall claude-rc-revive
rm -r ~/.local/state/rc-revive
License
MIT
Metadata
Release files for claude-rc-revive 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| claude_rc_revive-0.1.0.tar.gz | 33.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| claude_rc_revive-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 49.7 kB
Release files / claude_rc_revive-0.1.0.tar.gz
| Download URL | claude_rc_revive-0.1.0.tar.gz |
|---|---|
| Size | 33.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ffb740fe7e1e0889376f69d6407517207e56a3d78c2e3f4442437f74f1d28e57
|
|
BLAKE2b-256 checksum How to use checksums |
0d3a3bbee11b2800444a9ad80fa6cf34ebb727f8df92441f07d59e918684a1c0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / claude_rc_revive-0.1.0-py3-none-any.whl
| Download URL | claude_rc_revive-0.1.0-py3-none-any.whl |
|---|---|
| Size | 16.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
545db6710bf2e990a328297517d5f4f9d9f1bd350bee57598dc981b88fa9ca25
|
|
BLAKE2b-256 checksum How to use checksums |
1b613cb36e80c6ad4f1f2338ffacb11449865e339185db4a487b521e7a5a42d0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.11 {"installer":{"name":"uv","version":"0.11.11","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for claude-rc-revive 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.