mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-11-14 10:39:32 +01:00
fix(remote): load a remote session's scrollback from the remote tmux
A remote SSH session's local pane runs `ssh -t … tmux new-session -A` (or
`attach`), so the local tmux only sees the remote tmux client's full-screen
repaints and keeps a fraction of the history: measured 48 of 279 lines while
output streamed, none after a reattach. The remote pane, where the shell
runs, keeps all of it.
A full-history load (`GET /api/sessions/:id/terminal?full=1`) of a remote
session now reads the scrollback rows from the remote pane in one ssh round
trip (`#{history_size}` + `capture-pane -S -<N> -E -1`, exact `=name:`
target, newest bytes kept by a remote `tail -c`), and the local capture
reads only its visible frame (`-S 0`), spliced below them
(`PaneCaptureOptions.scrollbackOverride`). The local frame and caret are
kept because the live stream keeps drawing into the local pane.
Fail-soft and bounded: connection options from buildSshConnectionArgs(),
the shared remote-ssh limiter (a slot waited for longer than 1.5 s is given
up), a 5 s timeout, and a 30 s per-host back-off after any failure, which
keeps the local capture as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
aa3730aace
commit
b33d6da58a
7 files changed
+449
-2
No files matched your search
@@ -163,6 +163,7 @@ import {
|
||||
toAttachedSessionRemote,
|
||||
toSessionRemote,
|
||||
} from '../../remote-hosts.js';
|
||||
import { fetchRemoteScrollback } from '../../remote-pane-history.js';
|
||||
import {
|
||||
checkDockerAvailable,
|
||||
checkDockerConfigDrift,
|
||||
@@ -3116,6 +3117,19 @@ export function registerSessionRoutes(
|
||||
maxCaptureBytes: terminalBufferMaxBytes,
|
||||
}
|
||||
: {};
|
||||
// A remote session's local pane only sees the remote tmux client's repaints,
|
||||
// so its own scrollback is a fraction of the real one: read that from the
|
||||
// remote tmux and splice it above the local frame. Null (host unreachable,
|
||||
// no remote session, back-off) keeps the local capture as before.
|
||||
if (isFullReload && session.remote && muxName && captureOpts.historyLimitLines !== undefined) {
|
||||
const remoteScrollback = await fetchRemoteScrollback(
|
||||
session.remote,
|
||||
session.id,
|
||||
captureOpts.historyLimitLines,
|
||||
terminalBufferMaxBytes
|
||||
);
|
||||
if (remoteScrollback !== null) captureOpts.scrollbackOverride = remoteScrollback;
|
||||
}
|
||||
const liveMuxBuffer =
|
||||
muxName && typeof ctx.mux.captureActivePaneBuffer === 'function'
|
||||
? ctx.mux.captureActivePaneBuffer(muxName, captureOpts)
|
||||
|
||||
Reference in new issue
Block a user