mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-06 07:29:42 +02:00
fix(run,terminal): merge-time fixes for the Instance count stepper and capture geometry
#454: the behaviour the PR adds had no test, so a regression test drives runGrok() at tabCount 3 and asserts three quick-start POSTs with sequential w<n>-<case> names (verified to fail against master's session-ui.js). Each caller now reads the count BEFORE its opening banner and announces it there, the way runClaude() already did, so a launch no longer prints two headers and a launch with another session already active still says how many are starting. runClaude() calls the shared _readTabCount() instead of its own copy of the 1..20 clamp, and that helper optional-chains the element read, since hoisting it above each caller's try block would otherwise let a missing #tabCount throw where the launch-error path cannot report it. #435: sizeMovedUnderLoad derived from data.source alone. `mux-visible` is not sufficient: a failed display-message cursor query makes capturePaneBuffer skip the snapshot repaint and return the raw capture, which the route still labels mux-visible, so a size that moved during such a load bought a full forced reload to repair a frame that was never positioned. It now tests Number.isFinite(data.captureRows) like its two siblings. Plus the invariants and CLAUDE.md lines promised on #435: a visible capture reports its geometry and omits it when nothing was positioned, the comparison runs on mux-visible only, and the replay is capped at one attempt and latches per session when it cannot converge. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -4,44 +4,11 @@
|
||||
|
||||
fix(terminal): replay a pane capture at the geometry it was taken at
|
||||
|
||||
A visible-frame capture repaints each row at an absolute position, counting up
|
||||
to the pane's height and out to the pane's width. A terminal shorter than that
|
||||
clamps every address past its own height onto its last line, so the overflow
|
||||
rows overwrite one another and the rows underneath are lost. Against a 50-row
|
||||
pane, a 30-row terminal rendered 28 of a 45-line command and drew the surviving
|
||||
frame twice. A narrower terminal damages the same frame a second way: each row
|
||||
is painted out to the pane's own width, so the browser wraps every painted row,
|
||||
and the wrap on the last one scrolls the whole frame up by a row.
|
||||
|
||||
Nothing in the response said what geometry the frame was built for, so the
|
||||
client could not detect either case. A capture now reports the geometry it was
|
||||
really taken at through `capturedGeometry` on `PaneCaptureOptions`, and the
|
||||
terminal response carries it as `captureCols` and `captureRows`. Both fields are
|
||||
absent unless the response really carries a capture, since a body that was never
|
||||
positioned has no geometry to describe. When a captured pane is taller or wider
|
||||
than the terminal, or the size that produced the capture did not survive the
|
||||
load, `selectSession` replays once at the size that stuck.
|
||||
|
||||
That comparison runs on a visible-frame response only. A full-history response
|
||||
is linear scrollback closed by a relative cursor move, and a byte-history
|
||||
response carries no row alignment at all, so a size mismatch damages neither and
|
||||
a replay repairs neither. The distinction matters because the first load of
|
||||
every non-shell session per page takes the full-history path, where a replay
|
||||
would capture the whole tmux scrollback a second time.
|
||||
|
||||
Two guards keep the replay to the one pass that can converge. `resizeRetry` caps
|
||||
it at a single attempt, so two competing fits cannot trade replays forever. A
|
||||
pane already drawing at the size the client just requested is left alone, which
|
||||
is the signature of a clamp rather than a race: `getTerminalDimensions()` floors
|
||||
at 40x10 while `fitAddon.fit()` does not, so a terminal narrower than 40 columns
|
||||
or shorter than 10 rows reports a pane permanently bigger than itself and would
|
||||
otherwise replay on every tab switch without ever converging.
|
||||
|
||||
One case is still reported rather than repaired. A pane can be too tall because
|
||||
`Session.resize` declined the resize outright, which it does for a small
|
||||
viewport while a desktop viewport's size claim is live. The retry re-sends the
|
||||
same declined resize and captures the same pane, so it costs the one capped
|
||||
attempt and the frame is shown as it is. Repairing it means deciding who owns
|
||||
the pane size while a desktop claim is live, which is a policy question this
|
||||
does not touch. The reported geometry still helps, because the client can see
|
||||
the mismatch at all rather than being blind to it.
|
||||
Opening a session could draw a frame built for a pane bigger than your terminal. A
|
||||
taller pane wrote its overflow rows onto the last line and lost the rows underneath
|
||||
(against a 50-row pane, a 30-row terminal rendered 28 of a 45-line command and drew
|
||||
the survivors twice), and a wider one wrapped every row and scrolled the whole frame
|
||||
up by one. The terminal response now reports the geometry the capture was really
|
||||
taken at, so the browser can see the mismatch and replay once at the size that stuck.
|
||||
A pane that cannot be sized to fit is diagnosed once per session instead of on every
|
||||
tab switch.
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
"aicodeman": patch
|
||||
---
|
||||
|
||||
fix(run): make the Instance count stepper work for every non-Claude mode
|
||||
|
||||
The Instance count stepper next to the Run button only ever applied to Claude.
|
||||
Setting it to 3 and launching OpenCode, Codex, Gemini, Antigravity, Pi, OMP, Grok or
|
||||
DeepSeek started exactly one session, with no error and no hint that the control had
|
||||
done nothing. All eight now launch the count you asked for, and the opening banner
|
||||
says how many are starting.
|
||||
Reference in New Issue
Block a user