You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat: hot-swap upgrade — replace the binary while every tab stays live
Add src/hotswap.rs: on 'tab-atelier upgrade' / POST /upgrade the running
process re-execs the binary installed at its own path, handing each
tab's PTY master fd (CLOEXEC cleared) plus a pid-validated JSON manifest
across the exec. Because exec keeps the pid, tab shells remain our
children — process groups, controlling TTYs, cgroups, and nftables
rules are untouched, so agents and builds inside the tabs never notice.
The new image adopts the fds at boot (AdoptedPty mirrors alacritty's
Unix Pty: same poller tokens, SIGCHLD pipe, waitpid exit detection)
instead of forking shells; grid contents restore through the existing
saved-output replay and the carried raw ring bytes re-seed viewer
scrollback. PTY readers freeze during the handoff so unread bytes wait
in the kernel and are parsed by the new binary — nothing is lost.
Adopted tabs skip exactly the work that assumes a fresh shell: agent
auto-resume (would double-launch the still-running claude), the GUI
net-off bubblewrap respawn (still jailed), the headless nftables
teardown/re-apply (would blip enforcement; only the gating DNS resolver
is respawned), the cgroup stale reap, and the agent reaper's provenance
record (removed at swap so the new boot can't SIGKILL the inherited
fleet). A shell that dies mid-swap falls back to a normal fresh fork;
a failed exec rolls back fully and the old binary keeps running.
Trigger surface: POST /upgrade (master token, 409 when no binary at the
re-exec path, 501 on Windows), 'upgrade' subcommand on both binaries,
docs/hot-swap.md, openapi.yaml entry.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LTkVxFVGsaywyG4iJyTyvc
Copy file name to clipboardExpand all lines: README.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -97,6 +97,7 @@ The `.deb` lays out the following under FHS-standard paths:
97
97
- Tabs, working directories, and full terminal output persisted across restarts
98
98
- Active tab selection restored on startup
99
99
-**Agent auto-resume**: tabs that were running `catbus-agent` or `claude` at last save reopen with `catbus-agent --resume <uuid>` / `claude --resume <uuid>` typed into the freshly-spawned shell
100
+
-**Hot-swap upgrade**: `tab-atelier upgrade` re-execs the newly installed binary in place, handing every tab's live PTY across — shells (and the agents running in them) are never restarted. See [docs/hot-swap.md](docs/hot-swap.md)
100
101
101
102
**Preferences**
102
103
- Theme selection (Dark, Tomorrow Night Blue)
@@ -226,6 +227,7 @@ Selected routes:
226
227
|`DELETE`|`/tabs/{idx}`| Close a tab |
227
228
|`POST`|`/tabs/rotate-tokens`| Revoke all per-tab share tokens (share links 401) — master only |
228
229
|`POST`|`/master-token/reset`| Hot-swap the master API token (old token 401s) — master only |
230
+
|`POST`|`/upgrade`| Hot-swap onto the newly installed binary, tabs stay live ([docs](docs/hot-swap.md)) — master only |
229
231
230
232
Bind addresses for both listeners are configurable in preferences (`api_addr`, `api_tls_addr`); pass `--read-only` to launch a second instance that serves the API but refuses every mutating verb.
0 commit comments