Skip to main content

Native Comet message rail delivery

This delivery replaces EXEPERT Desktop's top-aligned checkpoint list and delayed generic tooltip with Comet/Zeron's compact, centered message rail. It applies to Native Chat, Codex, and DSH's Chat and Trajectory views. The implementation starts from 4d64ddf94867b8f06ad1dcf1d671ffe4bf71ed92 and is delivered on codex/native-comet-message-rail.

Hovering a mark shows its prepared prompt and reply on the next rendered frame. Activating a prompt scrolls to its stable message key over 500 ms. Grouping keeps long conversations compact while keyboard navigation still reaches every loaded prompt.

Viewport placement and appearance

The rail occupies an overlay inside the actual message viewport, between the toolbar and composer. Its stack is vertically centered in that viewport, so composer height changes and DSH Trajectory's different surrounding layout do not leave the marks too high. The previous asymmetric rail offsets are removed.

All dimensions below are logical pixels unless stated otherwise.

PropertyDelivered behavior
Width thresholdHidden below 768 px conversation width; eligible at 768 px
Normal visibilityAt least two loaded user prompts
Placement16 px from the viewport's left edge; 26 px rail width
Transcript guttersSymmetric 48 px when visible; 12 px when hidden
Mark hit row10 px high with 3 px between rows
Stack capacityAt most 12 evenly distributed groups; reserves 24 px above and below when calculating capacity, with a minimum of one slot
Idle markRounded 12 x 2 px line, white at 16 percent opacity
Active or hovered markPrimary text color at 80 percent opacity
Hovered widthImmediately expands to 20 px

Crossing the width threshold remeasures the virtualized rows with the new symmetric gutters while preserving the current scroll anchor. Existing transcript top padding and per-row spacing remain in their source adapters.

Groups partition all resident prompts into contiguous ranges. Mouse previews and clicks represent the active prompt when it belongs to the group, otherwise the group's first prompt. Keyboard selection makes its chosen prompt the group's representative. The ranges are recomputed when the loaded prompt count or available viewport height changes.

Shared component and hover isolation

ui/message_rail.rs defines the crate-private MessageRailView. It receives prepared checkpoint snapshots from the existing source adapters and owns hover, keyboard selection, focus, and preview dismissal. Its activation event contains the conversation scope and stable message-row key.

The application mounts the rail as a sibling of the cached transcript under their shared viewport. This boundary matters in the pinned GPUI renderer: marking a nested rail dirty also dirties its cached transcript ancestor and can redraw visible message rows. Sibling mounting allows hover to redraw the rail while the transcript remains cached.

Native Chat also separates row projection from excerpt preparation and skips transcript reconciliation when the projected scope and rows are unchanged. Its row content revision includes the message role so a role change invalidates the cache. Setup and conversations without an interactive rail retain their existing rendering path.

TranscriptCheckpointRailState now keeps resolved resident snapshots and reuses the same Rc when their content is unchanged. The old checkpoint ListState, generic tooltip, per-list marker focus plumbing, and obsolete preview harness are removed. Source-specific transcript virtualization and message identity remain in the existing adapters.

Because the overlay and transcript are siblings, the 26 px rail strip forwards wheel, middle-button, and motion-cancellation input through a scoped event to the shared scrolling core. The overlay does not install a full-viewport input handler.

Immediate preview and keyboard behavior

The rail constructs one visible deferred() / anchored() card beside the selected mark. There is no hover timer or opacity animation. Moving quickly between marks replaces that card immediately.

Preview propertyValue
Width280 px, constrained to the window
Window clearanceAt least 8 px
Corners and padding12 px radius and 8 px internal padding
Text spacing6 px
SurfaceOpaque EXEPERT SURFACE_2, subtle border, and shadow
Prompt textScalable 12 px equivalent; at most 160 characters
Reply textScalable 11 px equivalent; at most 200 characters
Grouped marksAdditional prompt count

The existing Unicode-safe excerpt truncation and turn-aware reply pairing are preserved. Empty replies are omitted. The old YOU and AGENT headings and divider are removed.

The anchor uses a zero-size absolute wrapper at the mark's center so flex alignment cannot move it vertically. An outer 8 px padding wrapper enforces the window clearance even when the pinned renderer's normal anchor snapping would allow a card closer to the edge. Backdrop blur is unavailable in this renderer, so the card uses Comet's opaque fallback with EXEPERT's neutral colors.

Keyboard focus uses the same preview surface. Arrow keys, Home, End, Enter, and Space retain per-prompt navigation even when several prompts share a mark. Keyboard input takes precedence over a lingering mouse hover, and focus follows the selected stable key into its new group after prepends or height changes. Mouse activation resolves its representative at event time, including when the input mode changes before another paint.

Preview state is cleared when its owner disappears, the conversation changes, or the rail becomes hidden. Event handlers reject stale conversation scopes. Existing rail IDs, message-row identities, and accessible labels are retained.

Codex's special history-only rail remains available when there are no loaded prompts and an explicit older-history loader exists. It is centered in the same host and observes the width threshold. Activation navigates to that loader; hovering or grouping never fetches history.

Stable-key scroll animation

TranscriptScrollState::glide_to_key() adds a rail-specific 500 ms timeline using Comet's CSS cubic Bezier curve (0.42, 0, 0.58, 1). It runs on the existing frame scheduler and keeps its destination as a stable message key.

Measured destinations use pixel-distance interpolation. Unmeasured destinations use fractional row positions and a moving estimate of visible row height, then switch to measured positioning as the destination is realized. Small upward steps stay within existing overdraw where possible. Tail anchors are normalized before row interpolation, and completion lands at the target row with zero offset.

Streaming row revisions and history prepends in the same conversation preserve the original animation start time and frame generation. Each frame resolves the target key against the current rows, allowing its index and measured height to change without restarting the 500 ms timeline.

Wheel input, scrollbar dragging, another navigation action, middle-button interaction, conversation changes, and target eviction cancel or replace the glide. Reduced motion jumps immediately; enabling it during a glide finishes at the destination. Existing search jumps, the 140 ms wheel animation, and middle button autoscroll keep their existing behavior.

Verification record

The implementation was validated on Windows on 2026-09-03 with Rust 1.96.0-x86_64-pc-windows-msvc and the existing locked dependencies.

CheckObserved result
Desktop compiler check, all targetsPassed
Desktop library suite533 passed, zero failed, four ignored
Focused integration and source-contract suites92 passed; two native harness tests ignored in the ordinary integration run
Production message-rail native harnessPassed when explicitly enabled
Existing native transcript overdraw harnessPassed when explicitly enabled
Existing native width-reflow anchor harnessPassed when explicitly enabled
Rustfmt on changed Rust filesPassed
Debug desktop binary buildPassed; desktop/target/debug/exepert-desktop.exe
Docusaurus production buildPassed with this page registered in Desktop delivery records
Whitespace and patch validationgit diff --check passed

The grouping tests cover 0, 1, 2, 12, 13, and 500 prompts, available-height limits, the 767/768 px boundary, representative selection, Unicode excerpts, existing reply pairing, and snapshot reuse. Scroll tests cover the easing curve, exact 500 ms completion, stable targets during streaming and prepends, cancellation, and reduced motion.

The native harness uses the production MessageRailView and shared scrolling core with resident deterministic rows. It exercises four transcript surface identities at 96, 144, and 192 DPI, giving 12 surface/DPI cases. These correspond to 100, 150, and 200 percent scaling. The harness checks:

  • stack centering within one logical pixel of the message viewport;
  • mark geometry, card size, anchor position, and window clearance;
  • the correct single card on the next rendered frame after hover;
  • no transcript render, row render, or reconciliation caused by rapid hover;
  • width gating, retained scroll offset, composer-height changes, and regrouping;
  • keyboard selection, mouse/keyboard transitions, focus migration, and eviction;
  • conversation switches and navigation to the explicit history loader; and
  • native scroll frames through streaming, prepends, unmeasured upward movement, exact final targets, and wheel cancellation over the rail.

DPI cases send WM_DPICHANGED only to the harness's own native window. They do not change Windows display settings. Adapter mounting and routing are covered by source contracts; the native fixture does not open live provider-backed conversations. Physical monitor changes and a manual session in the full application were not performed for this rail delivery.

Reproduction commands

Run the desktop commands from the desktop directory so its Cargo configuration is applied:

cargo +1.96.0-x86_64-pc-windows-msvc check -p exepert-desktop --all-targets --locked
cargo +1.96.0-x86_64-pc-windows-msvc test -p exepert-desktop --lib --locked
cargo +1.96.0-x86_64-pc-windows-msvc test -p exepert-desktop --test codex_ux_contract --test emoji_ux_contract --test chat_ux_contract --test chat_presentation_ux_contract --test dsh_ux_contract --test response_timing_ux_contract --test message_actions_ux_contract --test codex_timeline_render --locked -- --quiet
cargo +1.96.0-x86_64-pc-windows-msvc test -p exepert-desktop --lib native_message_rail_geometry_hover_keyboard_glide_and_dpi --locked -- --ignored --test-threads=1 --nocapture
cargo +1.96.0-x86_64-pc-windows-msvc test -p exepert-desktop --test codex_timeline_render native_virtual_transcript_realizes_overdraw_in_child_view --locked -- --ignored --test-threads=1 --quiet
cargo +1.96.0-x86_64-pc-windows-msvc test -p exepert-desktop --lib native_width_reflow_restores_a_nonzero_stable_row_offset --locked -- --ignored --test-threads=1 --quiet
cargo +1.96.0-x86_64-pc-windows-msvc build -p exepert-desktop --bin exepert-desktop --locked

Run the documentation and patch checks from the repository root:

pnpm.cmd --dir docs-site exec docusaurus build
git diff --check

Complete repository change inventory

Relative to baseline 4d64ddf, this delivery contains 14 paths: three additions, 11 modifications, and no deletions or renames. This includes every implementation, test, attribution, and documentation change in the delivery commit.

StatusPathChange
MTHIRD_PARTY_NOTICES.mdExtends the pinned Zeron MIT attribution to the adapted message-rail layout, grouping, direct preview rendering, and scroll easing
Mdesktop/exepert-desktop/src/app.rsMounts the rail beside cached transcripts in each source viewport; separates Native Chat excerpts from row projection, skips unchanged reconciliation, and includes message role in content revisions
Mdesktop/exepert-desktop/src/ui/codex_transcript.rsReplaces the old marker list with a shared rail entity, scoped activation/input subscriptions, viewport measurement, symmetric gutters, stable-key glide integration, and preserved explicit history-loader navigation
Mdesktop/exepert-desktop/src/ui/dsh_transcript.rsIntegrates the shared rail with DSH Chat/Trajectory projections, measured viewport geometry, width-sensitive gutters, input routing, reduced motion, and frame scheduling
Adesktop/exepert-desktop/src/ui/message_rail.rsImplements shared geometry, bounded grouping, immediate preview rendering, mouse and keyboard selection, stale-state cleanup, accessibility, scoped events, and pure rail tests
Adesktop/exepert-desktop/src/ui/message_rail/native_tests.rsExercises the production rail and shared scrolling core in native GPUI, including DPI, geometry, hover isolation, focus, resize, history, streaming, and navigation
Mdesktop/exepert-desktop/src/ui/mod.rsRegisters the crate-private message-rail module
Mdesktop/exepert-desktop/src/ui/native_chat_transcript.rsAdds projection matching and the shared rail entity; preserves setup rendering while integrating viewport measurement, gutters, input routing, stable-key navigation, and scroll lifecycle
Mdesktop/exepert-desktop/src/ui/transcript.rsReplaces legacy marker/tooltip UI state with reusable resident snapshots; bounds replies to 200 characters; implements the 500 ms keyed glide, easing, measured/unmeasured interpolation, timeline preservation, cancellation, reduced motion, and focused unit tests
Mdesktop/exepert-desktop/tests/codex_timeline_render.rsRemoves the obsolete synthetic checkpoint-list assertions while retaining the native virtualized-row overdraw and cached-sibling regression harness
Mdesktop/exepert-desktop/tests/codex_ux_contract.rsLocks shared rail ownership, immediate previews, stable IDs, cached sibling mounting, projection guards, scoped activation, paired excerpts, gutters, and explicit history loading
Mdesktop/exepert-desktop/tests/emoji_ux_contract.rsUpdates transcript gutter expectations to the shared symmetric layout
Adocs-site/docs/architecture/native-comet-message-rail-delivery.mdRecords behavior, architecture, compatibility, provenance, exact validation boundaries, reproduction commands, and this complete inventory
Mdocs-site/sidebars.tsAdds this page to Desktop delivery records

Compatibility and provenance

The adapted reference is Comet/Zeron commit b3fa51872f70c8f973c241b659cf0c166766f4f5, specifically crates/ui/src/rail.rs and crates/ui/src/motion.rs. Source comments and THIRD_PARTY_NOTICES.md retain the MIT attribution to Copyright (c) 2026 Wing. The reference checkout is unchanged.

All new interfaces are crate-private. Transcript virtualization, provider protocols, persistence, explicit history loading, and existing settings remain intact. This change adds no dependencies, renderer modifications, or settings migration.

The Git delivery consists of the documented feature commit and its normal merge into main. Generated Cargo binaries and Docusaurus output remain ignored. A release package, binary upload, hosted documentation deployment, or live provider request is not part of this Git delivery.