l0ng-aiandl0ng-ai af3928da1e fix(tree-sync): pay back a remote window's owed tree pull (#472)
* fix(tree-sync): pay back a remote window's owed tree pull

A window opening onto a remote workspace is empty until `hydrate` pulls
the machine's tree and rebuilds its tabs from it, and it has to be: an
empty window diffs into "close every tab", so `sync_window` holds
anything back until the pull lands. When the pull fails,
`owe_rehydration` records the debt and returns, on the promise in its own
doc comment that the next sync settles it — "which is what a reconnect
does through `on_link_up`".

`on_link_up` is called for `HostId::LOCAL` and nowhere else. On a remote
host the debt was only ever settled by a reconnect completing, by an edit
in the window, or by restarting the app. So a pull that failed while the
link stayed up was never noticed again: no reconnect, and an empty window
has nothing in it to edit. The window sat on the home page with every tab
and every shell still on the machine, and only a restart brought them
back.

Two ways to fail a pull with a healthy link, both routine. A `MachineGet`
can overrun its ten seconds on a slow link. And a `WorkspaceCreate` can
lose its race with `start_prime`, which runs the same create from the
other side of the same window opening — that one fires on every remote
workspace opened, and is only invisible because the workspace it usually
lands on is empty anyway.

So: arm a backed-off retry when the debt is taken on, drive it through
`sync_window` where the rules about whether a window may still adopt the
machine's layout already live, and stop treating a lost create as a
failure — read the tree again and hydrate from what is really there.
`on_link_up` is also wired to a remote link coming up, which is what the
comment always claimed: a link the switcher connects finishes no attempt,
so nothing told its windows the machine could be reached.

* fix(tree-sync): end the backoff with the run of failures, and stop shouting

Review follow-ups on the owed-pull retry.

The attempt count paces the retry, so it has to mean "failures in a row",
but it was only cleared when a hydration landed. A debt abandoned rather
than paid — a `Replace` dropped because the user filled the window in
themselves — and a prime that landed both left it standing, so the next
first failure waited the 30s cap on an outage that was already over. It
is now cleared wherever the run ends.

A window left open on a machine that is really gone retries forever by
design, which meant a warn and an info every ~45s for as long as it stayed
open. Once the backoff settles at its cap those lines stop being events
and become a fact about the machine, so they step down to debug. The retry
is exactly as persistent; only the volume drops.

Also: report the create's own refusal when the reread finds the workspace
still missing, and say at debug that the reread happened at all — the race
recovery was silent, so the extra round trip was invisible when reading a
log. And correct the comment on the window-gone guard: closing a window
drops its whole `WsState` through `forget`, debt and all, so nothing is
parked for the next opener.

Tests: the count ends with the run at all three sites, the level steps
down at the settle point, and the armed retry is driven through a real
timer (advance_clock) into the window-gone guard — the first coverage of
the retry actually firing rather than of the predicate it consults.

---------

Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>
2026-08-10 23:47:29 +08:00

tty7

tty7

A terminal workbench: persistent sessions, remote work, agents.

Pure Rust · GPU rendering on Zed's gpui · VT core from Alacritty


CI Version License Discord

English · 简体中文


tty7 with a tab sidebar of agent sessions across several repos, running Claude Code

Why

  • Performance — ~2× the throughput of Alacritty, Ghostty, or Kitty (benchmarks)
  • Persistent sessions — quit or reboot; your shells and supported agent sessions keep running, no tmux
  • Editor-grade input — suggestions, completion, highlighting, history search
  • Remote development — files, repos, panes, and git data stay on the remote machine
  • Native SSH — profiles, SFTP, port forwarding, and jump hosts
  • Agent-aware — Claude Code, Codex & co.: status, notifications, git context
  • CLI + Skills — agents create panes, run commands, and inspect output

Install

Native builds for each platform on Releases:

macOS …-macos-arm64.dmg · …-x86_64.dmg drag into Applications
Windows …-setup.exe · portable ….zip
Linux …-x86_64.AppImage chmod +x and run — X11/Wayland libraries bundled

What's inside

Editor-grade input ghost suggestions from history · explained tab completion · syntax highlighting · multi-line editing · click places the caret · ⌃ R fuzzy history
Window tabs & splits · ⌘ P palette · ⌘ F scrollback search · nine themes · IME
Agent-aware per-pane detection (18 CLIs): status dot · notifications · branch + diff · resume after reboot · tray icon when input is needed
Remote workspaces remote files, repos, changes, diffs, worktrees, tabs, and panes · reconnect from any client and continue where you left off
CLI + Skills bundled tty7 CLI · agent skill · pane/workspace control · real PTY commands · output, process, port, and agent status
SSH native russh stack: profiles with keychain secrets · SFTP panel · port forwarding · jump hosts · one-time, unprivileged tty7-server install

Terminal and keybinding reference: docs/features.md. The agent-facing CLI interface is documented in skills/tty7/SKILL.md.

Install the skill with:

npx skills add l0ng-ai/tty7

Benchmarks

Same machine, same day, same 155×40 grid — Apple M1 Pro, macOS 26.3.1, five-run averages (2026-07-04):

tty7 Alacritty Ghostty Kitty
Plaintext I/O — 11 MB cat (lower = better) 95 ms 239 ms 179 ms 185 ms
DOOM-fire frame rate (higher = better) 888 fps 485 fps 552 fps 617 fps
Cold-launch memory 116 MB¹ 105 MB 128 MB 130 MB

¹ GUI 105 MB + the persistent server 11 MB.

Methodology and one-command reproduction: scripts/bench/.


S
Description
A terminal workbench in pure Rust: shells, persistent sessions, SSH, coding agents. GPU-rendered on Zed's gpui, VT core from Alacritty.
Readme Apache-2.0
34 MiB
Languages
Rust 99.1%
Shell 0.5%
PowerShell 0.2%
Inno Setup 0.1%