Skip to content

Commit 432e6ba

Browse files
yotsudaclaude
andcommitted
docs(changelog): expand 0.10.0 with renderer overhaul (round 3, #4)
Adds the third major round to the 0.10.0 entry: cell-based CommandOutputRenderer initialised from a per-command VtLiteState snapshot, viewport-top tracking, alt-screen save/restore + placeholder, soft-wrap re-join, regex-prompt cap (Start/End + SGR back-up), node integration script OSC-before-prompt. Documents the known limitation: first alt-screen run after one or more prior non-alt commands on a fresh console may include ConPTY's post-exit redraw of session history in the response. Subsequent runs are clean. Fix deferred to a follow-up PR. Bumps date to 2026-04-20. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 24bb687 commit 432e6ba

1 file changed

Lines changed: 125 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 125 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
All notable changes to ripple are documented here. Format based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), versioning follows [Semantic Versioning](https://semver.org/).
44

5-
## [0.10.0] - 2026-04-19
5+
## [0.10.0] - 2026-04-20
66

7-
Two parallel rounds land in the same release. **(1) Live virtual-
7+
Three parallel rounds land in the same release. **(1) Live virtual-
88
terminal cursor tracking** — ripple now keeps an authoritative
99
VT-100 interpreter advanced from every PTY chunk and answers DSR
1010
(`\x1b[6n`) cursor-position queries from real state instead of the
@@ -20,7 +20,18 @@ worker-owned spill file (`%TEMP%\ripple.output\` on Windows,
2020
returns a head + tail preview embedding the spill path. Inline
2121
`execute_command` and deferred `wait_for_completion` now flow
2222
through a shared finalize-once boundary so both delivery modes
23-
return the same `CommandResult` shape.
23+
return the same `CommandResult` shape. **(3) Command-output
24+
extraction is rebuilt as a per-command fork of the live VT
25+
interpreter** (closes #4) — at OSC C the worker snapshots the
26+
session-wide `_vtState` and hands the snapshot to a new
27+
`CommandOutputRenderer` initialised from it. ConPTY's
28+
post-alt-screen and post-prompt redraw bursts target cells whose
29+
baseline values match what's being rewritten, so a per-cell change
30+
detector recognises them as idempotent overwrites and they stay
31+
out of the AI-facing MCP response. Alt-screen entry/exit collapses
32+
to an `[interactive screen session]` placeholder; soft-wrapped
33+
logical lines are re-joined at render time so a narrow PTY can't
34+
fragment a single `git log --oneline` entry.
2435

2536
### Added
2637
- **`Services/VtLiteState.cs`** — the VT-100 interpreter formerly
@@ -171,6 +182,117 @@ return the same `CommandResult` shape.
171182
untouched — the human still sees a live progress bar exactly as
172183
the shell intended; only the AI-facing `output` collapses.
173184

185+
### Renderer overhaul (round 3 — closes #4)
186+
187+
#### Added
188+
189+
- **`Services/CommandOutputRenderer.cs`** — cell-based per-command
190+
fork of the live `VtLiteState`. Constructor accepts an optional
191+
`VtLiteSnapshot` baseline; rows are pre-populated from the
192+
snapshot grid, cursor / saved-cursor / scroll-region / SGR /
193+
alt-screen state carry over, and each baseline row stashes a
194+
`BaselineCells` immutable copy for the per-cell change detector
195+
at `Render` time. Implements CUU/CUD/CUF/CUB/CNL/CPL/CHA/VPA,
196+
CUP/HVP, EL/ED, ECH, DCH/ICH, IL/DL, save/restore, real
197+
alt-screen save/restore semantics, and viewport-top tracking
198+
that increments on LFs crossing the snapshot's viewport bottom
199+
so subsequent CUP coordinates land on the rows ConPTY actually
200+
intends.
201+
- **`VtLiteState.Snapshot()` + per-row soft-wrap + active-SGR
202+
tracking.** New `VtLiteSnapshot` deep-copy record carries
203+
primary + alternate grids, soft-wrap flags, cursor, saved
204+
cursor, scroll region, alt-screen flag, and the active SGR
205+
carry-over. `WriteChar`'s auto-wrap now flips a per-row
206+
"continued from above" flag (set on wrap, cleared on hard LF /
207+
EraseLine mode 2 / EraseDisplay; shifted in lockstep with grid
208+
rows on `ScrollUp` / `ScrollDown`). `RecordSgr` accumulates
209+
non-reset SGR sequences since the last `\e[m` / `\e[0m` /
210+
leading-0 compound reset so the snapshot's `ActiveSgr` can seed
211+
the renderer's first-cell prefix.
212+
- **`CompletedCommandSnapshot.VtBaseline`** — optional snapshot
213+
field threaded through `CommandTracker``ConsoleWorker`
214+
`CommandOutputFinalizer.Clean`. The worker snapshots
215+
`_vtState` (session-wide, not the tracker's per-OSC-C-reset
216+
one) right before forwarding the OSC C event so the renderer
217+
receives the screen state ConPTY has at command start.
218+
- **Soft-wrap re-joining at render time.** Rows whose
219+
`ContinuedFromAbove` flag is set are appended to the previous
220+
emitted line without an inter-row newline, so a long `git log
221+
--oneline` entry that auto-wrapped at the PTY's right margin
222+
reaches the AI as one logical line.
223+
- **Alt-screen as placeholder.** Entry switches to a separate row
224+
list for alt-buffer writes; exit restores the main-buffer
225+
cursor and inserts a single `[interactive screen session]` line
226+
in the rendered output. ConPTY's post-exit redraw of the saved
227+
main buffer is naturally absorbed by the per-cell baseline diff
228+
(cells already hold the expected values).
229+
- **Regex-prompt cap.** `RegexPromptDetector.Scan` returns
230+
`(Start, End)` per match (was end-only). Worker fires synthetic
231+
`CommandFinished` + `PromptStart` at `Start` so the visible
232+
prompt characters are excluded from the
233+
`[commandStart, OSC A]` window — fixes trailing `(Pdb)` /
234+
`DB<N>` / `>` leak for pdb / perldb / python / and any other
235+
regex-prompt REPL. `Start` also backs past contiguous non-reset
236+
SGR sequences immediately preceding the prompt match (REPL
237+
prompt decoration), bounded at any reset SGR (the prior
238+
command's "stop coloring" closer) and at any non-SGR byte
239+
including whitespace.
240+
- **23 new tests** covering snapshot independence, soft-wrap
241+
flags, SGR set/reset/compound, baseline-skip-pre-command,
242+
ConPTY-repaint-idempotent, alt-screen+baseline placeholder,
243+
soft-wrap re-join, regex-prompt Start vs End semantics,
244+
prompt-decoration SGR back-up, and reset-SGR halt. All 728
245+
tests pass.
246+
247+
#### Changed
248+
249+
- **Bare `\r` is now cursor-reset only (no row clear).** Matches
250+
what the human sees in the live terminal — verified
251+
empirically against Git Bash via ripple MCP. The legacy
252+
"clear the row on bare CR" is intentionally lossier than
253+
terminal spec; with the cell-based renderer in place, the spec
254+
semantics produce identical results for properly-formed
255+
progress bars (which use `\r\x1b[K` or full-replacement
256+
rewrites) and slightly truthier results for short rewrites
257+
(which match the live-terminal residue).
258+
- **Node.js integration script (`integration.js`) emits OSC bytes
259+
BEFORE the visible prompt** instead of after. Same pattern
260+
pwsh's prompt function has always used. Eliminates the trailing
261+
`> ` on every node REPL command. OSC sequences are zero-width
262+
so emitting them at any cursor position is safe; the previous
263+
"after" ordering was conservative but unnecessary.
264+
265+
#### Fixed
266+
267+
- **Issue #4`echo … | grep` on Git Bash via ConPTY no longer
268+
drops trailing match lines.** ConPTY emits a screen-redraw
269+
burst around prompts that contains real grep output
270+
(`cherry`, `elderberry`) and absolute cursor positioning the
271+
legacy `StripAnsi` silently dropped, leaving only the first
272+
match (`banana`) in the cleaned output. The new renderer
273+
processes the cursor positioning correctly and the per-cell
274+
baseline diff treats matching repaint as idempotent — all
275+
three matches survive intact.
276+
- **Trailing `\e[m` reset SGR is no longer lost** when the
277+
output ends with `text\r\n\e[m`. `Render` flushes pending SGR
278+
to the last non-empty row's `TrailingSgr` before iterating
279+
rows, so end-of-output color resets reach downstream consumers
280+
instead of leaving "color stuck on" state.
281+
282+
#### Known limitation
283+
284+
- **First alt-screen run on a fresh console after one or more
285+
prior non-alt commands** may include ConPTY's post-exit redraw
286+
of the visible session history in the MCP response (typically
287+
3–6 prior prompts). Subsequent alt-screen runs in the same
288+
console produce clean output. Cause: a subtle divergence
289+
between `ConsoleWorker._vtState`'s incremental session state
290+
and ConPTY's screen view; the first ConPTY full redraw syncs
291+
them. Fix deferred to a follow-up PR; mitigation is to either
292+
ignore the first noisy response or to discard one warm-up
293+
command. Affects only alt-screen workflows (vim, less, htop)
294+
on the very first such command of a session.
295+
174296
## [0.8.0] - 2026-04-16
175297

176298
First round of **debugger adapters** plus three new REPL adapters and

0 commit comments

Comments
 (0)