revive-ssh — the Revive SSH server agent
Terminal sessions that survive disconnects, sleeping phones and server restarts, shared between your phone (Revive SSH app) and any terminal on the server. Runs as a regular user, opens no ports: everything goes through your existing sshd.
Install
curl -fsSL https://get.vendo.bot/revive-ssh/install.sh | sh
or from the signed package repositories:
# Debian / Ubuntu
curl -fsSL https://get.vendo.bot/revive-ssh/revive-ssh.gpg | sudo tee /usr/share/keyrings/revive-ssh.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/revive-ssh.gpg] https://get.vendo.bot/revive-ssh/apt stable main" \
| sudo tee /etc/apt/sources.list.d/revive-ssh.list
sudo apt update && sudo apt install revive-ssh
# Fedora / RHEL / Rocky / Alma
sudo curl -fsSL -o /etc/yum.repos.d/revive-ssh.repo https://get.vendo.bot/revive-ssh/rpm/revive-ssh.repo
sudo dnf install revive-ssh
# openSUSE
sudo zypper addrepo https://get.vendo.bot/revive-ssh/rpm/revive-ssh.repo && sudo zypper --gpg-auto-import-keys install revive-ssh
Repository key: Revive SSH repository, RSA 4096, ID 7EB65DC6B62D78BA. One static
binary (amd64, arm64); its own updates are signed (Ed25519) and verified before they run.
The packages are only a starting point: newer signed versions also update themselves
into ~/.local/share/revive-ssh. Snap and AUR (revive-ssh-bin) packages are in preparation;
until they are published, use install.sh on Arch and other systems.
Manual install without curl | sh:
curl -fsSLo revive-ssh https://get.vendo.bot/revive-ssh/latest/revive-ssh-linux-amd64 # ARM: -linux-arm64
chmod +x revive-ssh && mkdir -p ~/.local/bin && mv revive-ssh ~/.local/bin/
Language
The agent speaks English, or Polish when LANG/LC_ALL starts with pl. Notifications it
sends itself (long commands, AI tool hooks) use each phone's language.
Everyday use
revive-ssh
Shows a menu of your sessions (name, what runs in it, last activity):
Revive SSH — sessions
1) web npm 10-31 19:45 b2472ce0e6
n) new session
q) QR code — pair a phone
x) exit
- a number attaches this terminal to that session;
nstarts a new one: asks for a name, offers to create~/<name>and start there, and for a command to run at start; it can be saved as a template, shown later ass1,s2… (stored in~/.config/revive-ssh/templates.json);qshows the pairing QR code for the phone.
The very first run (no sessions, no paired phone) goes straight to the QR code. Scan it in the app (Add server → Scan QR code), or scan it with the phone's camera.
Detach from a session with Ctrl+\ — it keeps running. Open the same session in the app later and everything that happened meanwhile is there, scrollable.
Commands
| Command | What it does |
|---|---|
revive-ssh new [name] [--dir DIR] [--cmd COMMAND] |
new session (optionally named, started in DIR, with COMMAND typed into the fresh shell) and attach |
revive-ssh connect [--history] <name\|id> |
attach this terminal to a session (--history: replay everything, not just the screen); revives one interrupted by a reboot |
revive-ssh ls |
sessions with name, foreground program, last activity |
revive-ssh kill <name\|id> |
end a session |
revive-ssh share <session> <user> [--view] / share |
let another user of this machine join your session (--view: watch only); no arguments: who has access and who is connected |
revive-ssh unshare <session> [<user>] |
remove access (no user — everybody); connected users are dropped at once |
revive-ssh handover <session> <user> [--yes] |
offer the session to another user for 10 min; they get its history and directory, yours ends |
revive-ssh connect <owner>/<session> / take <owner>/<session> |
join a session shared with you / take over one handed to you |
revive-ssh pair [--host H[,H2]] [--port P] [--local] [--name N] |
pair a phone (QR); addresses and port are detected, --local leaves out the public IP, --name sets the server name shown in the app |
revive-ssh devices / revoke <id\|all> |
paired phones / remove a phone's key |
revive-ssh devices add --key K [--name N] [--platform P] [--json] [--expires UNIX [--view] [--confirm ID.TOKEN]] |
authorize another device key (the app does this when pairing a computer, docs/device-pairing.md); with --expires: a browser key until then, Revive sessions only, --view = watch only, --confirm = this server vouches to the relay that the browser may reach it, from its own address (docs/browser-access.md) |
revive-ssh notify [--title T] TEXT |
push notification to paired phones |
revive-ssh hooks [status\|install\|uninstall] [tool…\|all] |
AI tools: push when they finish or ask for permission (Claude Code, Codex, Gemini CLI, Antigravity, Cursor, opencode, Aider) |
revive-ssh status / version |
version, updates, sessions, devices |
revive-ssh update [--check] [--channel stable\|beta] [--disable\|--enable] [--rollback] |
signed self-update (also checked automatically at most every 6 h; an admin can block it for everyone with autoupdate = false in /etc/revive-ssh/policy.conf) |
Phone and computer, one session
Several clients can be attached at once; the screen size follows the one you
typed on last, so a phone in your pocket does not squeeze the session on your
monitor. Typical day: start a long job or a coding agent in revive-ssh new web at the desk,
continue on the phone on the go, revive-ssh connect web back at the desk.
Sharing with another user of the machine
revive-ssh share web patryk --view # patryk: revive-ssh connect lukasz/web
revive-ssh handover web patryk # patryk: revive-ssh take lukasz/web
Shared: the other user works in your session as you (or only watches with --view); attached
clients see who joins and leaves, and every client hears on which devices the session is open (“Session open on 2 devices: iPhone, Windows · PC”). Handed over: they get a new session of their own with your
history and directory, and yours ends — running programs do not move. The kernel checks who
connects (SO_PEERCRED); no ports, no passwords, and never for root. Details: docs/sharing.md.
While a handover offer is pending, your crontab holds one line
(@reboot … revive-ssh boot-check # revive-ssh handover): if the server restarts before the
other user takes the session, your phone gets a push saying so, with the command to offer it again.
The line goes away by itself once no offer is pending; the rest of your crontab is left untouched.
Without cron there is no such notification (noted in ~/.local/state/revive-ssh/agent.log).
Notifications
make build; revive-ssh notify "build: $?"
revive-ssh hooks install # every AI tool found on this account
revive-ssh hooks install codex # or just the ones you name; `revive-ssh hooks` shows the state
hooks install adds one entry to each tool's own config (Claude Code ~/.claude/settings.json,
Codex ~/.codex/hooks.json, Gemini CLI ~/.gemini/settings.json, Antigravity
~/.gemini/config/hooks.json, Cursor ~/.cursor/hooks.json, opencode
~/.config/opencode/plugins/revive-ssh.js, Aider ~/.aider.conf.yml), keeps a backup and leaves
your own hooks alone; hooks uninstall removes only ours. Codex asks you to approve a new hook once
(/hooks).
Long commands notify by themselves: when a program that ran at least 2 minutes
finishes while no phone or terminal is attached, you get "Zakończono: make (3 min 12 s)";
the tap opens that session. Change or turn off with notify_long = 300 / notify_long = 0
in ~/.config/revive-ssh/config.
Notifications are end-to-end encrypted: the phone gives the agent its own key over SSH, the agent
encrypts the title and text (AES-256-GCM), and our push relay, Apple and Google only see a generic
"Revive SSH: new notification". The relay stores neither tokens nor text. Revoking a phone
(revive-ssh revoke) also stops its notifications.
Files
~/.local/state/revive-ssh/— session history (survives restarts;history = offin~/.config/revive-ssh/configkeeps it in RAM only), push tokens and keys (push.json, 0600), the app's diagnostic log (app.log, only if you turn on sending it in the app)~/.config/revive-ssh/—config, session templates~/.ssh/authorized_keys— one line per paired phone, removed byrevive-ssh revoke
Uninstall
revive-ssh hooks uninstall
revive-ssh revoke all
rm -f ~/.local/bin/revive-ssh; rm -rf ~/.local/share/revive-ssh ~/.local/state/revive-ssh ~/.config/revive-ssh
If it came from a package, remove the package as well (sudo apt remove revive-ssh,
sudo dnf remove revive-ssh, sudo zypper remove revive-ssh).
Privacy and terms
Privacy policy · Terms of Use · contact: info@electricentropy.eu
License
Business Source License 1.1 — see LICENSE. Free for production use except a competing offering; becomes Apache 2.0 on 2030-10-30.