Skip to content

(remote): forward the CLI's title through tmux on attach so an attached remote row is not mute - #293

Merged
devsuitup merged 5 commits into
mainfrom
fix/290-tmux-set-titles
Sep 14, 2026
Merged

devsuitup merged 5 commits into
mainfrom
fix/290-tmux-set-titles

Conversation

@devsuitup

@devsuitup devsuitup commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Closes #290.

Overnight trace on v0.0.79 (.work-files/switchboard/trace-2026-09-13-nuit.md, measure 1): two remote sessions attached for 9 h 20 emitted zero osc.title and zero busy mutation while their transcripts kept growing. Since the row-ownership rule (#273) an attached remote row is driven by the local-pty path, i.e. by the CLI's OSC title — and tmux forwards that title to the outer terminal only when set-titles is on. Measured on the host: tmux 3.6, set-titles* off, set-titles-string* "#S:#I:#W - \"#T\" #{session_alerts}" (inherited defaults).

  • buildAttachCommand prefixes set -t <target> set-titles on \; set -t <target> set-titles-string '#T' \; in solo and shared mode alike. These are session options, so while a Switchboard client is attached every other client of that session sees the CLI title as its outer-terminal title — the one deliberate exception to the (remote): make a solo tmux attach look and behave like a local terminal #253 rule, stated in the context doc; a mute row was judged the worse defect. #T is single-quoted so the remote shell does not read # as a comment.
  • The probe reads both options back; inherited (starred) values parse as null. The two title options are restored on every detach (shared included, so a first shared attach does not become the new baseline); status/mouse/window-size stay solo-only. tmux prints option values in its own escaped form and never re-parses an argv value, so the parser reverses the escapes tmux 3.6 emits (outer quote pair, , , backslash-any), pinned by a table of twenty values measured live on the host; the restore passes the plain value shell-single-quoted.
  • main.js unchanged: the OSC extraction is already shared between local and attached PTYs.

Live check on a throwaway tmux server on the same host (not the production session): a pane whose title is ⠋ hello attached with these two options over ssh -tt delivers \e]0;⠋ hello\a to the outer terminal — the pane title unwrapped, glyph first, exactly what classifyTitleActivity keys on. The production session's options were not touched (set-titles* off still).

Tests: test/remote-attach.test.js (+14): probe parsing incl. the quoted-string wire form, exact attach commands in both modes, restore segments and round trips, attach/detach integration offsets, and a pin that the #T title classifies as busy through the same regex wireSessionPty uses. Rationale in .ai/contexts/session-cache.md ("Remote hosts — tmux attach", set-titles).

…ed remote row is not mute

Since the row-ownership rule (#273) an attached remote row is driven by the
OSC title only, and tmux forwards it to the outer terminal only with
set-titles on; the default is off and the default format wraps the pane
title, so the classifier never saw the glyph. The attach command now sets
set-titles on and set-titles-string '#T' in solo and shared mode alike, the
probe records the previous values and the solo detach restores them.
Closes #290.
…k its own quoted token

Shared attaches also set the two title options, so they are restored on a
shared detach too (the other three stay solo-only), which removes the
baseline ratchet after a first shared attach. set-titles-string is kept as
the raw token tmux prints and restored inside shell single quotes only,
letting tmux re-parse its own quoting.
…oken back

tmux never re-parses an argv value, so the printed token cannot be handed
back as-is; the parser now reverses the escapes tmux 3.6 actually emits
(outer quote pair, \n, \t, backslash-any), pinned by a table of twenty
values measured on the host.
…nt remains

Two clients attached to the same tmux session would otherwise switch title
forwarding off under each other. Detach probes the live client count and
keeps the title options when another client is still there; the base
options keep the solo rule. Three more measured quoting rows in the table.
…nt rule holds

The detach-time client count ran after the local ssh client was killed and
on a fresh connection, so our own client had usually vanished and a single
remaining peer read as 'nobody but us'. The probe now runs first, bounded
by a dedicated 5 s timeout, then the kill, then the restore.
@devsuitup
devsuitup merged commit 155fcef into main Sep 14, 2026
10 checks passed
@devsuitup
devsuitup deleted the fix/290-tmux-set-titles branch September 14, 2026 07:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(remote): an attached remote row stays mute because tmux does not forward the CLI's title

1 participant