Merge pull request #601: fix(terminal): load a shell from tmux's rendered history, not the byte recording

Conflicts resolved against #583 and #588:
- One history-depth field: #583's `historyLines` / `capturedHistoryLines`
  (reported as `paneHistoryLines`) is kept, and #601's lines cut now reads it
  instead of a second `capturedHistorySize`. #601's `alternateOn` /
  `capturedAlternateOn` joins it, and the one display-message format string
  ends `#{history_size} #{alternate_on}`.
- selectSession keeps #588's full=1 switch for panes with no scrollback, gated
  off remote and Docker sessions, and #601's SHELL_LOAD_QUERY for shells.
- computeHistoryTruncationNotice names a line count when paneHistoryLines is
  known (#583) and otherwise uses #601's remainder wording.
- docs: api-reference lists both historyLinesCut and paneHistoryLines; the
  notice invariant keys on history_size while the shell's automatic load is
  the one place alternate_on decides.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-10-13 17:59:07 +02:00
commit 36f8afdaba
15 files changed
+402 -50

No files matched your search

+12 -9
View File
@@ -543,20 +543,23 @@ client that opens many concurrent waits against one session will still hit the c
What a session's terminal shows, for a client to replay: `data.terminalBuffer`,
with `source` (`mux-visible`, `mux-full-history` or `history`), `truncated`,
`truncationReason`, `fullSize`, and `captureCols`/`captureRows` when the pane's
geometry was read. `paneHistoryLines` (present when the body is a pane capture whose
geometry was read, like `captureCols`/`captureRows`) is the number of scrollback rows tmux holds above the visible frame, which is the
most a `full=1` request can add. `truncated` describes the byte stream instead: for a
pane with `paneHistoryLines: 0` (a fullscreen CLI in the alternate screen) the bytes a
`tail` cut dropped are earlier repaints that no request returns. The capture runs
synchronous tmux calls on the server; the `Server-Timing` header reports `capture`,
`prepare` and `total`.
`truncationReason`, `fullSize`, `historyLinesCut` (a `lines=` bound left older
lines in tmux, so the remainder is more than `fullSize - retainedBytes`), and
`captureCols`/`captureRows` when the pane's geometry was read. `paneHistoryLines`
(present when the body is a pane capture whose geometry was read, like
`captureCols`/`captureRows`) is the number of scrollback rows tmux holds above the
visible frame, which is the most a `full=1` request can add. `truncated` describes
the byte stream instead: for a pane with `paneHistoryLines: 0` (a fullscreen CLI in
the alternate screen) the bytes a `tail` cut dropped are earlier repaints that no
request returns. The capture runs synchronous tmux calls on the server; the
`Server-Timing` header reports `capture`, `prepare` and `total`.
| Query | Meaning |
|---|---|
| `full=1` | tmux's scrollback, not only the visible frame (`source: 'mux-full-history'`), ending with a relative cursor move back to the pane's caret. |
| `tail=<bytes>` | Keep the newest `<bytes>` of the result (`truncationReason: 'tail'` when it cut). |
| `lines=<n>` | With `full=1` only: read at most `<n>` lines of tmux history above the visible frame. An integer of at least 1, clamped to the configured history limit; absent or malformed, the whole limit (100,000 lines by default), as before. `truncated` and `truncationReason` describe byte cuts only, not this bound. Without it a full capture reads all of that history before `tail` cuts it, so a client that keeps a fixed number of lines (the tile grid sends its xterm's scrollback plus its rows) should send it. |
| `lines=<n>` | With `full=1` only: read at most `<n>` lines of tmux history above the visible frame. An integer of at least 1, clamped to the configured history limit; absent or malformed, the whole limit (100,000 lines by default), as before. When a bound below the configured limit left older lines in tmux (its `history_size` is deeper), `truncated` is true with `truncationReason: 'tail'`; a byte cap still reports `'capped'`. Without it a full capture reads all of that history before `tail` cuts it, so a client that keeps a fixed number of lines (the tile grid sends its xterm's scrollback plus its rows) should send it. |
| `alt=recording` | With `full=1` only: if the pane is in the alternate screen (a nested tmux, where tmux keeps no history, or any full-screen app such as vim or less while it is open), answer with the visible frame over the byte recording instead (`source: 'mux-visible'`, `tail` applied as without `full=1`). Shells' automatic loads send it. |
## The `codeman agent` CLI (client over these endpoints)