···11# Changelog
2233-## Unreleased
33+## 0.7.0
44+55+### Supervisor
66+- Add session supervisor: `pty supervisor start` runs a foreground process that watches for sessions with `strategy=permanent` tag and restarts them on exit with exponential backoff (1s→16s, max 5 restarts per 60s)
77+- `pty supervisor start/stop/status/forget/reset` commands
88+- `pty supervisor launchd install/uninstall` for macOS auto-start — bundles the supervisor into a portable JS file via esbuild, uses absolute paths to node (no PATH dependency), `KeepAlive=true`
99+- Supervision is configured entirely through tags (`strategy=permanent` or `strategy=temporary`)
1010+- `strategy=permanent`: restart on exit with backoff. `strategy=temporary`: clean up on exit
1111+- Supervisor detects dead processes via PID liveness check (handles external kills where `exitedAt` is never set)
1212+- Supervisor state persisted in `~/.local/state/pty/supervisor/` (restart counts survive supervisor restarts)
1313+- `pty supervisor reset <name>` clears failed status for retry
1414+- New event types: `session_restart`, `session_failed`, `supervisor_start`, `supervisor_stop`
1515+- 10s periodic scan as safety net for missed `fs.watch` events
4161717+### Project files
518- Add `pty up` / `pty down` commands to start and stop sessions defined in a `pty.toml` project file
66-- `pty.toml` supports named sessions with commands and optional tags
1919+- `pty.toml` supports named sessions with commands, tags, and an optional `prefix` for session naming
720- `pty up` accepts a directory argument (`pty up ./backend`) and session name filtering (`pty up dev serve`)
88-- Add `--tags` flag to `pty list` to display tags as `#key=value` hashtags
99-- Add session supervisor: `pty supervisor start` runs a process that watches for sessions with `strategy=permanent` tag and restarts them on exit with exponential backoff
2121+- `pty up` syncs tags from the toml to already-running sessions (without removing manually-added tags)
2222+- `pty up` stores `ptyfile` and `ptyfile.session` tags so the supervisor re-reads the toml on restart
2323+- `pty down` removes strategy tags and stops sessions (including supervised ones), warns about toml-managed sessions
2424+2525+### Mutable tags
1026- Add `pty tag <name> key=value` / `pty tag <name> --rm key` to set and remove tags on running or exited sessions
1111-- Add `pty supervisor start/stop/status/forget` commands
1212-- Add `pty supervisor launchd install/uninstall` for macOS auto-start
1313-- Supervision is configured entirely through tags (`strategy=permanent` in pty.toml tags or via `pty tag`)
1414-- `pty list` shows `[permanent]`, `[temporary]`, and `[failed]` markers for supervised sessions
1515-- `pty down` refuses to stop supervised sessions (use `pty supervisor forget` first)
1616-- New event types: `session_restart`, `session_failed`, `supervisor_start`, `supervisor_stop`
2727+- `pty tag <name>` with no args shows current tags
2828+- Warns when modifying tags on toml-managed sessions (changes will be overwritten by `pty up`)
1729- Atomic metadata writes (write-to-temp + rename) to prevent partial reads
1818-- Add `pty peek --wait "text"` to block until text appears on screen, with optional `-t` timeout
3030+3131+### Peek and wait
3232+- Add `pty peek --wait "text"` to block until text appears on screen, with optional `-t` timeout (seconds)
1933- Add `pty peek --full` to show full scrollback (not just viewport)
2020-- Add `pty events --wait <type>` to block until a specific event type occurs
3434+- Add `pty events --wait <type>` to block until a specific event type occurs, with optional `-t` timeout
3535+3636+### CLI improvements
3737+- Add `--cwd` flag to `pty run` to start a session in a specific directory
3838+- Add `--tags` flag to `pty list` to display tags as `#key=value` hashtags
2139- Colorize `pty list` output: bold cyan session names, dimmed commands
2240- Interactive TUI list shows `[permanent]`/`[temporary]`/`[failed]` markers with color
2323-- Add `--cwd` flag to `pty run` to start a session in a specific directory without needing to `cd` first
4141+- `pty kill` on supervised sessions removes the strategy tag (supervisor won't restart it)
4242+- `pty kill` and `pty down` warn when stopping toml-managed sessions
4343+4444+### Fixes
4545+- Defensive `meta.args` fallback to `[]` in all display code (prevents crashes on old metadata)
4646+- Shell integration tests isolated from real session directory
4747+- Fix flaky TUI filter test (wait for list to re-render, not just input to appear)
24482549## 0.6.0
2650
+16
README.md
···5454pty run -a -- node server.js # create or attach if already running
5555pty run -e -- npm test # ephemeral: auto-remove on exit
5656pty run --tag owner=forge -- node srv.js # tag a session with metadata
5757+pty run --cwd /path -- node server.js # run in a specific directory
57585859pty list # show active sessions
5960pty list --tags # show sessions with tags (#key=value)
···6364pty attach -r myserver # reconnect, auto-restart if exited
6465pty peek myserver # print current screen and exit
6566pty peek --plain myserver # print as plain text (no ANSI)
6767+pty peek --full myserver # print full scrollback
6868+pty peek --wait "Listening" myserver # wait until text appears on screen
6969+pty peek --wait "Ready" -t 10 myserver # wait with timeout (seconds)
6670pty peek -f myserver # follow output read-only
67716872pty send myserver "hello" # send text (no implicit newline)
···8387pty kill myserver # terminate a running session
8488pty rm myserver # remove an exited session's metadata
8589pty gc # remove all exited sessions
9090+pty tag myserver role=web # set tags on a session
9191+pty tag myserver --rm role # remove a tag
9292+9393+pty supervisor start # start the session supervisor
9494+pty supervisor stop # stop the supervisor
9595+pty supervisor status # show supervised sessions
9696+pty supervisor forget myserver # stop supervising a session
9797+pty supervisor reset myserver # reset a failed session for retry
86988799pty up # start all sessions from ./pty.toml
88100pty up ./backend # start sessions from ./backend/pty.toml
···296308- **agent-teams** — live dashboard of a simulated AI agent hierarchy with real-time updates
297309298310Run them with `node --experimental-strip-types demos/{name}/main.ts`. Each demo includes unit tests and PTY integration tests that exercise the testing library.
311311+312312+## Skill Reference
313313+314314+For AI coding agents and automation, see **[docs/SKILL.md](docs/SKILL.md)** — a concise guide to running and managing background processes with pty, including session lifecycle, common patterns, and rules for well-behaved agents.
299315300316## Tab Completion
301317
+151
docs/SKILL.md
···11+# PTY — Run and manage background processes
22+33+Run `pty --help` to see the full command reference.
44+55+Use `pty` to run processes in managed terminal sessions. Prefer pty over raw
66+background commands (`&`, `nohup`, piping) for better lifecycle control,
77+readable output, and the ability to wait for results.
88+99+## When to use
1010+1111+- Running any long-lived or background process (dev servers, test suites, builds)
1212+- Interactive CLI tools that need a real terminal (auth via keychain, TUI, REPL)
1313+- Any task where you want to start work, do something else, then check results
1414+- Processes you may need to re-read output from later
1515+1616+## Session lifecycle
1717+1818+### 1. Create a detached session
1919+2020+```bash
2121+pty run -d --name <descriptive-name> --tag owner=<agent> -- <command> [args...]
2222+```
2323+2424+Use `--cwd` to run in a specific directory:
2525+2626+```bash
2727+pty run -d --name <name> --cwd /path/to/project --tag owner=<agent> -- <command>
2828+```
2929+3030+Tag sessions so they are identifiable. Never touch sessions you did not create.
3131+3232+### 2. Wait for the process to be ready
3333+3434+```bash
3535+pty peek --wait "expected text" --plain <name> -t 10
3636+```
3737+3838+Check the output to confirm the process has started (e.g. "Authenticated",
3939+"Listening", a prompt character).
4040+4141+### 3. Send input (if interactive)
4242+4343+```bash
4444+pty send <name> "your message here"
4545+pty send <name> --seq key:return
4646+```
4747+4848+For multi-step input use `--seq` chains:
4949+5050+```bash
5151+pty send <name> --seq "first line" --seq key:return
5252+```
5353+5454+Use `--with-delay` if the tool needs time between inputs:
5555+5656+```bash
5757+pty send <name> --with-delay 0.5 --seq "text" --seq key:return
5858+```
5959+6060+### 4. Wait for output and read results
6161+6262+Wait for specific text to appear:
6363+6464+```bash
6565+pty peek --wait "expected output" --plain <name> -t 120
6666+```
6767+6868+Read the full scrollback (not just the visible screen):
6969+7070+```bash
7171+pty peek --full --plain <name>
7272+```
7373+7474+Read just the current visible screen:
7575+7676+```bash
7777+pty peek --plain <name>
7878+```
7979+8080+Check recent events without following:
8181+8282+```bash
8383+pty events --recent <name>
8484+```
8585+8686+### 5. Clean up
8787+8888+Always kill sessions you created when done:
8989+9090+```bash
9191+pty kill <name>
9292+```
9393+9494+## Rules
9595+9696+- **Always use `--plain` with peek** so output is readable (no ANSI escapes)
9797+- **Always use `-t` (timeout)** on `--wait` so you don't block forever
9898+- **Always tag sessions** so they are identifiable and attributable
9999+- **Always clean up** — kill sessions when you are done
100100+- **Never touch sessions you did not create** — check `pty list --tags` if unsure
101101+- **Use `--full` when output may exceed the screen** — peek without it only
102102+ shows the visible terminal buffer
103103+104104+## Naming conventions
105105+106106+Name sessions by purpose: `gemini-review`, `test-runner`, `dev-server`, etc.
107107+Keep names lowercase with hyphens.
108108+109109+## Quick reference
110110+111111+| Action | Command |
112112+|---|---|
113113+| Create detached | `pty run -d --name <n> --tag owner=<a> -- <cmd>` |
114114+| Peek (plain) | `pty peek --plain <n>` |
115115+| Peek (full scrollback) | `pty peek --full --plain <n>` |
116116+| Wait for text | `pty peek --wait "text" --plain <n> -t 30` |
117117+| Send text | `pty send <n> "text"` |
118118+| Send enter | `pty send <n> --seq key:return` |
119119+| Recent events | `pty events --recent <n>` |
120120+| Follow events | `pty events <n>` |
121121+| List sessions | `pty list --tags` |
122122+| Kill session | `pty kill <n>` |
123123+124124+## Common patterns
125125+126126+### Run a dev server and wait for it
127127+128128+```bash
129129+pty run -d --name dev-server --tag owner=agent -- npm run dev
130130+pty peek --wait "Listening" --plain dev-server -t 30
131131+# Server is ready — do your work
132132+pty kill dev-server
133133+```
134134+135135+### Run tests and read results
136136+137137+```bash
138138+pty run -d --name tests --tag owner=agent -- npm test
139139+pty peek --wait "passed\|failed" --plain tests -t 120
140140+pty peek --full --plain tests
141141+pty kill tests
142142+```
143143+144144+### Run a build and check for errors
145145+146146+```bash
147147+pty run -d --name build --tag owner=agent -- npm run build
148148+pty peek --wait "error\|successfully" --plain build -t 60
149149+pty peek --full --plain build
150150+pty kill build
151151+```
+1-1
flake.nix
···29293030 # Generated from package-lock.json.
3131 # Regenerate with: nix run nixpkgs#prefetch-npm-deps -- package-lock.json
3232- npmDepsHash = "sha256-a7g3tIDb+6JKQxCTqnL1i3gps4LjTVjt8wf+TrDtPzY=";
3232+ npmDepsHash = "sha256-p9vkNBkSC8lQb23b2p5Exo3n/tlJrq8wuRoSjajpZgo=";
33333434 # node-pty has native code that needs these at build time
3535 nativeBuildInputs = with pkgs; [ python3 pkg-config ];