Skip to content

feat(engine): scrollback-commit primitive for inline mode#112

Merged
RtlZeroMemory merged 2 commits into
mainfrom
feat/scrollback-commit
Jun 11, 2026
Merged

feat(engine): scrollback-commit primitive for inline mode#112
RtlZeroMemory merged 2 commits into
mainfrom
feat/scrollback-commit

Conversation

@RtlZeroMemory

Copy link
Copy Markdown
Owner

Summary

Adds engine_commit_scrollback() (engine ABI 1.3.0 → 1.4.0, library 1.4.0 → 1.5.0): stage drawlist-rendered rows for emission into terminal scrollback above the inline live region. This is the Ink <Static> / Bubble Tea Println primitive — the missing piece for agent-style CLIs that stream finished content (chat messages, log lines, tool output) into terminal history while a live region keeps rendering below.

Motivated by building a coding-agent TUI on Rezi; the companion Rezi PR exposes this as app.printAbove(...).

Design

  • Commit content is a normal drawlist executed at submit time into an isolated viewport cols × rows framebuffer — wrappers reuse their entire existing rendering pipeline; drawlist resources (DEF/FREE) act on a transient snapshot and never persist. No-partial-effects: a failed call stages nothing.
  • Pure emitter (zr_diff_render_commit): relative re-anchor to the region top, per-row paint with baseline-SGR tail erase (EL — BCE-safe) and LF claims so earlier lines scroll into history, then a fresh-line claim that becomes the new region top. Returns terminal state with SCREEN_VALID cleared, so the live-region diff that follows re-establishes the inline baseline below the block — reusing the existing rebaseline machinery rather than inventing new repaint logic.
  • Present integration: staged blocks emit FIFO before the live-region diff, inside the same single flush and synchronized-update wrap (visually atomic). Staged blocks survive failed presents (retry-safe) and release only after a successful flush.
  • Bounded staging: ZR_COMMIT_ROWS_MAX (1024) per call, ZR_COMMIT_PENDING_ROWS_MAX (4096) total, 32 pending blocks; ZR_ERR_LIMIT beyond. INLINE mode only (ZR_ERR_UNSUPPORTED in ALT).

Test evidence

  • 7 new engine-level unit tests including a byte-exact present stream assertion (commit block + rebaseline + full repaint in one flush), ALT-mode rejection, rows bounds, FIFO ordering + post-success release, both pending caps, and staged-block retry after a failed present (via runtime out-budget raise).
  • 3 golden fixtures for the pure emitter (single row, multi-row styled, ALT rejection) — byte-pinned.
  • VT model extended with EL (CSI K) semantics.
  • All 12 ctest suites pass on clang debug, gcc debug, and ASan+UBSan; guardrails, version pins, clang-format, strict docs build all green.
  • Real terminal (tmux): examples/inline_status.c now commits checkpoint lines at progress quarters — verified live: committed lines stack in scrollback above the running region, survive app exit, and the prompt restores below the final frame.

Compatibility

  • ALT-mode and existing inline emission byte-identical (all prior goldens unchanged).
  • Additive API only; exact-match ABI negotiation moves to 1.4.0.

Checklist

  • Builds locally (or CI-only change)
  • Tests added/updated (unit/golden/fuzz/integration as appropriate)
  • Documentation updated (README.md and/or docs/ as appropriate)
  • mkdocs build --strict passes (docs changes)
  • bash scripts/clang_format_check.sh --all passes (formatting)
  • ABI/format impact assessed (engine ABI / drawlist / event batch)
  • Platform boundary preserved (no OS headers in core/unicode/util)

🤖 Generated with Claude Code

Adds engine_commit_scrollback(bytes, len, rows) (engine ABI 1.4.0, library
1.5.0): stage drawlist-rendered rows for emission into terminal scrollback
above the inline live region — the Ink <Static> / Bubble Tea Println
primitive that agent-style CLIs need.

Design:
- commit content is a normal versioned drawlist executed at submit time
  into an isolated framebuffer (viewport cols x rows); resources act on a
  transient snapshot; no-partial-effects on failure
- emission (zr_diff_render_commit, pure): relative re-anchor to region top,
  per-row paint with baseline-SGR tail erase (EL) + LF claims so earlier
  lines scroll into history, then a fresh-line claim re-anchors the region;
  SCREEN_VALID cleared so the following live diff rebaselines below
- present integration: staged blocks emit FIFO before the live-region diff
  inside the same single flush and synchronized-update wrap; staged blocks
  survive failed presents and release only after a successful flush
- bounded staging: ZR_COMMIT_ROWS_MAX per call, ZR_COMMIT_PENDING_ROWS_MAX
  total, 32 pending blocks

Tests: engine-level byte-exact present stream, ALT-mode rejection, rows
bounds, FIFO + release, pending caps, retry-after-failed-present; golden
fixtures for the pure emitter; VT model gained EL (CSI K).

Example: inline_status.c commits checkpoint lines at progress quarters
(verified in tmux: lines persist in scrollback during and after the run).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Inline scrollback commits: stage and emit committed rows into terminal history (FIFO, bounded per-call and total), survive failed presents, emit before re-establishing the live inline region, and guarantee no partial effects on failure
    • Example updated to periodically commit progress checkpoints into scrollback
  • Documentation

    • Rendering model, C ABI, and version pins updated for v1.5.0 / engine ABI v1.4.0
  • Tests

    • Added unit and golden tests covering commit semantics, ordering, limits, and emit sequences; VT model now supports EL (Erase in Line)

Walkthrough

This PR implements inline-mode scrollback commits: new APIs stage drawlist-rendered rows into engine-held framebuffers, present emits them before the live-region diff in a single flush, staged commits survive failed presents until released, version pins and limits are updated, and tests/docs/examples are added.

Changes

Inline Scrollback Commit Feature

Layer / File(s) Summary
Version Pins and Configuration Limits
include/zr/zr_version.h, docs/VERSION_PINS.md, include/zr/zr_config.h, CHANGELOG.md, docs/abi/versioning.md
Library version bumped to 1.5.0 and engine ABI minor to 1.4.0; new public macros ZR_COMMIT_ROWS_MAX and ZR_COMMIT_PENDING_ROWS_MAX define scrollback commit staging bounds; changelog updated.
Public API Declarations
include/zr/zr_engine.h, src/core/zr_diff.h
New public function engine_commit_scrollback() and new diff entrypoint zr_diff_render_commit() with INLINE-only contracts, bounds and no-partial-effects guarantees.
Diff Renderer Commit Implementation
src/core/zr_diff.c
Implements zr_diff_render_commit() and row-finalization helpers that close OSC8, reset SGR to baseline, erase to line end (EL), re-anchor cursor, claim a fresh inline line, and clear SCREEN_VALID on success; failures zero outputs.
Engine Commit Staging and State
src/core/zr_engine.c
Adds engine state for pending commit framebuffers and counters, zr_engine_commit_execute_block() to validate/execute drawlists into per-commit framebuffers, engine_commit_scrollback() to validate/enqueue commits, and a release helper for teardown.
Present-Phase Commit Emission and Release
src/core/zr_engine_present.inc
Adds helper to render pending commits via zr_diff_render_commit() before the live-region diff, prepends commit bytes to the output buffer in a single flush, and releases staged commits on successful present; commits survive failed presents.
Comprehensive Test Suite
tests/unit/test_engine_commit_scrollback.c, tests/golden/golden_commit_render.c, tests/golden/fixtures/*, tests/CMakeLists.txt
Unit tests validate mode enforcement, row bounds, FIFO ordering, pending-entry/rows caps, and survival across failed presents; golden tests validate zr_diff_render_commit() output and terminal-state effects; CMake updated to include new tests.
Documentation and Inline Example
docs/abi/c-abi-reference.md, docs/modules/DIFF_RENDERER_AND_OUTPUT_EMITTER.md, docs/user-guide/rendering-model.md, examples/inline_status.c
ABI and module docs describe staging/emission semantics, re-anchoring, and SCREEN_VALID clearing; user guide references inline-mode commits; inline_status.c now builds and submits single-row commit drawlists at progress checkpoints.
VT Terminal Model EL Support
tests/unit/zr_vt_model.c, tests/unit/zr_vt_model.h
VT model now supports CSI K (EL) mode 0 by erasing from cursor to end-of-line in the modeled grid; header docs updated to list supported sequences.

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly Related PRs

Poem

🐰 I built a little checkpoint line,

Staged it safe in buffer fine,
On present it hops into the scroll,
History keeps each tiny toll,
Hopping logs to mark the time.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.19% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main feature: a scrollback-commit primitive for inline mode, matching the core API additions and test coverage throughout the changeset.
Description check ✅ Passed The description is detailed and directly related to the changeset, covering design, test evidence, compatibility, and providing a clear summary of the scrollback-commit feature additions.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/scrollback-commit

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
tests/unit/zr_vt_model.c (1)

807-824: ⚡ Quick win

Consider extracting cursor-clamping + single-line-fill to a helper.

Lines 811–819 duplicate the cursor-clamping and rectangle-fill logic from zr_vt_model_erase_below (lines 108–116). Extracting this pattern to a small helper would eliminate the duplication and align with the guideline to prefer helper functions for repeated calculations.

♻️ Refactor to extract shared logic

Add a helper function before zr_vt_model_erase_below:

/* Fill from cursor to end of current line using current style. */
static zr_result_t zr_vt_model_erase_cursor_to_eol(zr_vt_model_t* m) {
  if (!m || m->cols == 0u || m->rows == 0u) {
    return ZR_ERR_INVALID_ARGUMENT;
  }
  const uint32_t y = (m->ts.cursor_y < m->rows) ? m->ts.cursor_y : (m->rows - 1u);
  const uint32_t x = (m->ts.cursor_x < m->cols) ? m->ts.cursor_x : (m->cols - 1u);
  zr_rect_t tail;
  tail.x = (int32_t)x;
  tail.y = (int32_t)y;
  tail.w = (int32_t)(m->cols - x);
  tail.h = 1;
  return zr_fb_fill_rect(&m->painter, tail, &m->ts.style);
}

Then simplify both call sites:

 if (!priv && intermediate == 0u && final == (uint8_t)'K') {
   const uint32_t mode = (param_count >= 1u) ? params[0] : 0u;
   if (mode == 0u && m->cols != 0u && m->rows != 0u) {
-    /* EL 0: erase from the cursor (inclusive) to the end of the line. */
-    const uint32_t y = (m->ts.cursor_y < m->rows) ? m->ts.cursor_y : (m->rows - 1u);
-    const uint32_t x = (m->ts.cursor_x < m->cols) ? m->ts.cursor_x : (m->cols - 1u);
-    zr_rect_t tail;
-    tail.x = (int32_t)x;
-    tail.y = (int32_t)y;
-    tail.w = (int32_t)(m->cols - x);
-    tail.h = 1;
-    const zr_result_t rc = zr_fb_fill_rect(&m->painter, tail, &m->ts.style);
+    const zr_result_t rc = zr_vt_model_erase_cursor_to_eol(m);
     if (rc != ZR_OK) {
       return rc;
     }
   }

And in zr_vt_model_erase_below:

 static zr_result_t zr_vt_model_erase_below(zr_vt_model_t* m) {
   if (!m) {
     return ZR_ERR_INVALID_ARGUMENT;
   }
   if (m->cols == 0u || m->rows == 0u) {
     return ZR_OK;
   }

-  const uint32_t y = (m->ts.cursor_y < m->rows) ? m->ts.cursor_y : (m->rows - 1u);
-  const uint32_t x = (m->ts.cursor_x < m->cols) ? m->ts.cursor_x : (m->cols - 1u);
-
-  zr_rect_t tail;
-  tail.x = (int32_t)x;
-  tail.y = (int32_t)y;
-  tail.w = (int32_t)(m->cols - x);
-  tail.h = 1;
-  const zr_result_t rc = zr_fb_fill_rect(&m->painter, tail, &m->ts.style);
+  const zr_result_t rc = zr_vt_model_erase_cursor_to_eol(m);
   if (rc != ZR_OK) {
     return rc;
   }
+  const uint32_t y = (m->ts.cursor_y < m->rows) ? m->ts.cursor_y : (m->rows - 1u);
   if (y + 1u >= m->rows) {
     return ZR_OK;
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/zr_vt_model.c` around lines 807 - 824, The cursor-clamping +
single-line-fill logic is duplicated in zr_vt_model.c (inside the branch
handling final 'K' and in zr_vt_model_erase_below); extract this into a small
static helper (e.g., zr_vt_model_erase_cursor_to_eol) that takes zr_vt_model_t*
m, clamps cursor_x/cursor_y against m->cols/m->rows, constructs the zr_rect_t
tail and calls zr_fb_fill_rect, returning its zr_result_t; replace both original
blocks with calls to this helper and propagate/return any non-ZR_OK result from
zr_fb_fill_rect.

Source: Coding guidelines

src/core/zr_diff.c (1)

2610-2680: ⚡ Quick win

Split zr_diff_render_commit() into smaller helpers.

This new function is well over the repo’s 50-line cap for C functions. Extracting validation/setup, row emission, and final-state rebasing would bring it back under the guideline without changing behavior.

As per coding guidelines, **/*.c: Functions should be 20-40 lines, with a maximum of 50 lines.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/zr_diff.c` around lines 2610 - 2680, zr_diff_render_commit is too
long; split it into three focused helpers without changing behavior: extract the
initial validation and setup (the null/arg checks, ctx init, sb init, initial
move and inline_rows_claimed) into a function like
zr_diff_render_commit_init(ctx,out_buf,out_cap,content,caps,initial_term_state,live_cols),
extract the per-row paint+finish loop (the paint_cols computation, loop calling
zr_diff_render_span and zr_diff_commit_finish_row) into
zr_diff_render_commit_paint_rows(ctx,content,live_cols), and extract the tail
logic (claim fresh line, truncation check, rebasing cursor/flags, setting
out_len/out_final_term_state) into
zr_diff_render_commit_finalize(ctx,out_len,out_final_term_state). Call these
three helpers from zr_diff_render_commit and keep all original checks/return
codes and zr_diff_zero_outputs behavior exactly the same.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/core/zr_diff.c`:
- Around line 2591-2607: zr_diff_commit_finish_row currently emits SGR then EL
(zr_emit_el0_clear_line_tail) without ensuring the terminal cursor is
re-anchored after zr_diff_render_span may have cleared
ZR_TERM_STATE_CURSOR_POS_VALID; update zr_diff_commit_finish_row to explicitly
re-anchor the cursor to ctx->ts.cursor_x (or emit an absolute cursor position)
before calling zr_emit_el0_clear_line_tail, e.g. invoke the library helper that
emits an absolute cursor column (or set the cursor position/flags and call
zr_emit_cursor_absolute equivalent) so that ZR_TERM_STATE_CURSOR_POS_VALID is
true and the EL (CSI K) clears from the intended column rather than a drifted
terminal column. Ensure references to ZR_TERM_STATE_CURSOR_POS_VALID,
ctx->ts.cursor_x, zr_emit_el0_clear_line_tail, and zr_diff_render_span are
considered when making the change.

---

Nitpick comments:
In `@src/core/zr_diff.c`:
- Around line 2610-2680: zr_diff_render_commit is too long; split it into three
focused helpers without changing behavior: extract the initial validation and
setup (the null/arg checks, ctx init, sb init, initial move and
inline_rows_claimed) into a function like
zr_diff_render_commit_init(ctx,out_buf,out_cap,content,caps,initial_term_state,live_cols),
extract the per-row paint+finish loop (the paint_cols computation, loop calling
zr_diff_render_span and zr_diff_commit_finish_row) into
zr_diff_render_commit_paint_rows(ctx,content,live_cols), and extract the tail
logic (claim fresh line, truncation check, rebasing cursor/flags, setting
out_len/out_final_term_state) into
zr_diff_render_commit_finalize(ctx,out_len,out_final_term_state). Call these
three helpers from zr_diff_render_commit and keep all original checks/return
codes and zr_diff_zero_outputs behavior exactly the same.

In `@tests/unit/zr_vt_model.c`:
- Around line 807-824: The cursor-clamping + single-line-fill logic is
duplicated in zr_vt_model.c (inside the branch handling final 'K' and in
zr_vt_model_erase_below); extract this into a small static helper (e.g.,
zr_vt_model_erase_cursor_to_eol) that takes zr_vt_model_t* m, clamps
cursor_x/cursor_y against m->cols/m->rows, constructs the zr_rect_t tail and
calls zr_fb_fill_rect, returning its zr_result_t; replace both original blocks
with calls to this helper and propagate/return any non-ZR_OK result from
zr_fb_fill_rect.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8cc2a5c3-dc85-4a63-9de5-59d5fdb6a654

📥 Commits

Reviewing files that changed from the base of the PR and between 8745d50 and ca3e6b5.

⛔ Files ignored due to path filters (2)
  • tests/golden/fixtures/commit_001_single_row/expected.bin is excluded by !**/*.bin
  • tests/golden/fixtures/commit_002_two_rows_styled/expected.bin is excluded by !**/*.bin
📒 Files selected for processing (23)
  • CHANGELOG.md
  • docs/VERSION_PINS.md
  • docs/abi/c-abi-reference.md
  • docs/abi/versioning.md
  • docs/modules/DIFF_RENDERER_AND_OUTPUT_EMITTER.md
  • docs/user-guide/rendering-model.md
  • examples/inline_status.c
  • include/zr/zr_config.h
  • include/zr/zr_engine.h
  • include/zr/zr_version.h
  • src/core/zr_diff.c
  • src/core/zr_diff.h
  • src/core/zr_engine.c
  • src/core/zr_engine_present.inc
  • tests/CMakeLists.txt
  • tests/golden/fixtures/commit_001_single_row/case.txt
  • tests/golden/fixtures/commit_001_single_row/expected.hex.txt
  • tests/golden/fixtures/commit_002_two_rows_styled/case.txt
  • tests/golden/fixtures/commit_002_two_rows_styled/expected.hex.txt
  • tests/golden/golden_commit_render.c
  • tests/unit/test_engine_commit_scrollback.c
  • tests/unit/zr_vt_model.c
  • tests/unit/zr_vt_model.h

Comment thread src/core/zr_diff.c Outdated
When a committed row ends on a drift-capable glyph (wide/non-ASCII), the
tracked cursor position is invalidated and EL would erase from whatever
column the terminal actually reached. Re-anchor to the painted edge with
absolute-column CHA (columns are drift-safe) before the tail erase.

Adds golden commit_004_wide_glyph_reanchors_tail pinning the CHA+EL bytes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@RtlZeroMemory

Copy link
Copy Markdown
Owner Author

Addressed in the latest commit: zr_diff_commit_finish_row now re-anchors to the painted edge with absolute-column CHA (drift-safe) before the tail EL whenever the row ended with an invalidated cursor position, and golden commit_004_wide_glyph_reanchors_tail pins the byte stream for a row ending on a width-2 CJK glyph.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
tests/golden/golden_commit_render.c (2)

136-151: ⚡ Quick win

Replace glyph-width/UTF-8 literals with named constants.

Line 143 (3u), Line 145 (2u), and Line 149 (0u) encode important glyph semantics; promoting them to local named constants/macros will make this helper less brittle and easier to audit.

As per coding guidelines, “Extract magic numbers to named constants with descriptive names instead of using bare literals.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/golden/golden_commit_render.c` around lines 136 - 151, In
zr_fb_set_wide, replace the magic literals (3u, 2u, 0u) with descriptive named
constants (e.g., WIDE_GLYPH_BYTES, WIDE_GLYPH_WIDTH, EMPTY_GLYPH_LEN) declared
at the top of the function or as local static macros; update uses in
memset/memcpy and assignments to lead->glyph_len, lead->width, cont->glyph_len
and cont->width (and any memset sizes) to use those constants so the intent
around glyph byte-length, display width and empty glyph state is explicit.

Source: Coding guidelines


161-185: ⚡ Quick win

Add Arrange/Act/Assert section markers in this golden test.

This test is long enough to benefit from the required test-structure markers for readability and maintenance (especially around fixture setup vs render call vs assertions).

As per coding guidelines, “Add section markers in long functions (/* --- Section Name --- /) and in tests (/ --- Arrange/Act/Assert --- /, / --- Validate/Compute/Emit --- */).”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/golden/golden_commit_render.c` around lines 161 - 185, Add test section
comment markers to the ZR_TEST_GOLDEN(commit_004_wide_glyph_reanchors_tail)
test: insert a /* --- Arrange --- */ before the fixture/setup code (zr_fb_init,
zr_fb_clear, zr_fb_set_* and initial state/caps/out buffer setup), a /* --- Act
--- */ immediately before the call to zr_diff_render_commit, and a /* --- Assert
--- */ before the assertions (ZR_ASSERT_TRUE checks and
zr_golden_compare_fixture) and teardown (zr_fb_release). Keep markers as
single-line C comments to improve readability without changing logic.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@tests/golden/golden_commit_render.c`:
- Around line 136-151: In zr_fb_set_wide, replace the magic literals (3u, 2u,
0u) with descriptive named constants (e.g., WIDE_GLYPH_BYTES, WIDE_GLYPH_WIDTH,
EMPTY_GLYPH_LEN) declared at the top of the function or as local static macros;
update uses in memset/memcpy and assignments to lead->glyph_len, lead->width,
cont->glyph_len and cont->width (and any memset sizes) to use those constants so
the intent around glyph byte-length, display width and empty glyph state is
explicit.
- Around line 161-185: Add test section comment markers to the
ZR_TEST_GOLDEN(commit_004_wide_glyph_reanchors_tail) test: insert a /* ---
Arrange --- */ before the fixture/setup code (zr_fb_init, zr_fb_clear,
zr_fb_set_* and initial state/caps/out buffer setup), a /* --- Act --- */
immediately before the call to zr_diff_render_commit, and a /* --- Assert --- */
before the assertions (ZR_ASSERT_TRUE checks and zr_golden_compare_fixture) and
teardown (zr_fb_release). Keep markers as single-line C comments to improve
readability without changing logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a48fc4d1-9554-454d-b15a-69077ef1d881

📥 Commits

Reviewing files that changed from the base of the PR and between ca3e6b5 and 47fda61.

⛔ Files ignored due to path filters (1)
  • tests/golden/fixtures/commit_004_wide_glyph_reanchors_tail/expected.bin is excluded by !**/*.bin
📒 Files selected for processing (4)
  • src/core/zr_diff.c
  • tests/golden/fixtures/commit_004_wide_glyph_reanchors_tail/case.txt
  • tests/golden/fixtures/commit_004_wide_glyph_reanchors_tail/expected.hex.txt
  • tests/golden/golden_commit_render.c
✅ Files skipped from review due to trivial changes (2)
  • tests/golden/fixtures/commit_004_wide_glyph_reanchors_tail/case.txt
  • tests/golden/fixtures/commit_004_wide_glyph_reanchors_tail/expected.hex.txt
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/core/zr_diff.c

@RtlZeroMemory
RtlZeroMemory merged commit 8a17e48 into main Jun 11, 2026
27 checks passed
@RtlZeroMemory
RtlZeroMemory deleted the feat/scrollback-commit branch June 11, 2026 13:30
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.

1 participant