pty experimental
Lifecycle
A session's lifecycle is a policy you set with flags and tags. No supervisor daemon watches over your sessions. Instead, a periodic gc pass reads the tags and makes them true.
When the program exits
By default, a finished session reaps itself: it removes its own entry, so it doesn't linger in pty list. You can change that.
- Set
PTY_REAP_ON_EXIT=falseto preserve finished sessions. Their final screen stays readable withpty peekuntilgcsweeps them. - Tag a session
keep=trueto keep it even past a sweep, until you remove it yourself. - Start it with
--ephemeralto reap it on any shutdown and leave no trace.
pty kill stops a session and keeps its record. pty rm removes the record.
gc: stateless reconciliation
pty gc is a single pass that you run on a short timer. Each pass:
- Respawns sessions tagged
strategy=permanentwhenever their program exits or vanishes. - Stops flapping. A permanent session that keeps dying right after a respawn is marked
flapping, and gc stops respawning it until you step in. - Kills orphans. A session tagged
parent=<name>is stopped once its parent is gone, so sidecars never outlive the thing they serve. - Sweeps finished sessions that nobody asked to keep.
There's no restart counter in memory and no long-running supervisor to crash. Every pass works out what you want from the files on disk. If something can't start yet, because a disk isn't mounted at boot for example, the next pass tries again.
pty gc --dry-run # show what gc would do, and change nothing
Declaring a project's sessions
A project can declare its sessions in a pty.toml and bring them up together:
[sessions.serve]
command = "bin/serve"
tags = { strategy = "permanent" }
[sessions.dev]
command = "npm run dev"
pty up # start every session in ./pty.toml
pty down # stop them
A permanent session from a pty.toml re-reads the file when gc respawns it, so your edits take effect on the next restart.