Skip to main content

Native transcript navigation and source UX delivery

This document records the native Rust/GPUI delivery that makes long EXEPERT Desktop conversations easier to read and navigate. It covers two connected increments built from baseline commit b356c453bd2e339a69b41dca3768d8f53d31948b:

  1. hard Codex activity folding, browser-style middle-button auto-scroll, and loaded user-message checkpoint rails; and
  2. compact paired checkpoint previews plus responsive icon-first EXEPERT, Codex, and DSH source tabs.

The delivery changes presentation and process-local transcript interaction only. Codex App Server history remains authoritative. Codex and DSH paging, search, storage, settings, protocol ownership, and retention are unchanged. No PostgreSQL, Docker, Supabase, migration, or new Rust dependency was added.

Delivered behavior

AreaDelivered contractSurfaces
Codex activity foldingCommands, tools, developer activity, and reasoning summaries start with only a bounded one-line summary mounted; expansion alone mounts the full projected body and structured detailsCodex
Always-visible contentWarnings, user messages, assistant commentary, and final answers remain fully visibleCodex
Disclosure identityExpanded state is process-local and keyed by server, task, turn, and item; stable item-qualified element IDs replace index-derived activity IDsCodex
Middle-button auto-scrollAn unmodified middle click toggles vertical auto-scroll with a visible anchor, 12 px dead zone, linear speed, 1,800 px/s cap, and 50 ms frame clampNative Chat, Codex, DSH Chat, DSH Trajectory
Motion cancellationA second middle click, left/right click, wheel input, Escape, checkpoint jump, programmatic jump, or scope/surface change cancels auto-scrollAll four transcript surfaces
Boundary behaviorReaching the top or bottom pauses movement without disarming it; reversing pointer direction resumes movementAll four transcript surfaces
User checkpointsLoaded user rows produce independently virtualized, stable-key markers with chronological loaded-window ordinalsAll four transcript surfaces
Checkpoint keyboard UXEnter/Space activates a marker; Up/Down/Home/End navigate markers; the active marker tracks the latest user row at or before the first visible transcript row, or the first loaded marker when none precedes itAll four transcript surfaces
Paired previewHover and keyboard focus open the same compact card with primary user text and an optional muted resident agent responseAll four transcript surfaces
Codex response truthOnly an authoritative same-turn AgentFinal can appear beneath a Codex user checkpointCodex
DSH response truthOnly a completed same-turn assistant/message can appear; chunks and model boundary records are excludedDSH Chat, DSH Trajectory
Omitted-history cueWhen no resident Codex user row exists and an older page can actually load, an unnumbered marker jumps to LOAD OLDER HISTORY without requesting dataCodex
Source selectorLocal EXEPERT, Codex, and DeepSeek marks replace text-only tabs; icons remain visible and the selected label appears at measured header widths of 720 px or moreDesktop Chat header
Source accessibilityStable IDs, ARIA names/selection, focus rings, hover tooltips, focus tooltips, and Enter/Space activation are preservedDesktop Chat header

Interaction architecture

TranscriptScrollState owns stable bookmarks, adaptive wheel motion, middle-button auto-scroll, tail-follow interaction, and animation generation. TranscriptCheckpointRailState separately reconciles loaded user markers and their focus handles. Checkpoints carry only bounded process-local excerpts and stable row keys; they never carry an App Server cursor or trigger paging.

The transcript views remeasure resident rows when rail presence changes. This prevents cached row geometry from overlapping a newly visible rail while the existing stable-key bookmark preserves the reader's anchor.

Hard Codex activity folding

The earlier visual line clamp did not remove long command or developer bodies from the render tree. The replacement uses distinct render branches:

  • collapsed rows mount a Unicode-aware single-line summary only;
  • expanded rows mount complete projected text and allowlisted structured details;
  • collapsing unmounts the full body and remeasures the affected row;
  • live reasoning no longer expands itself automatically;
  • warnings bypass activity folding and remain visible; and
  • source-copy actions retain the complete projected text even while the row is visually collapsed.

The disclosure button exposes truthful expanded state, state-aware chevrons, keyboard focus styling, and stable IDs derived from the qualified item key. Hidden/raw reasoning remains excluded upstream and cannot be revealed by the control.

Middle-button auto-scroll

The auto-scroll session stores the click anchor, current pointer, velocity, last frame time, and generation. Pointer displacement inside 12 px is neutral. Beyond that dead zone, velocity grows linearly and is capped at 1,800 px/s. Elapsed frame time is capped at 50 ms so a delayed frame cannot cause a large jump.

Starting auto-scroll pauses tail-follow. Reaching a list boundary produces no jitter and does not deactivate the session. A second middle click or any explicit competing navigation cancels the session. Reduced-motion mode keeps the functional anchor while omitting decorative animation.

The four surfaces share the motion engine but retain their existing source- specific reconciliation and focus-restoration paths.

Checkpoints and compact previews

Checkpoint identity comes from the stable transcript row key, not the loaded ordinal. Loading older history can renumber accessible labels without changing marker identity. Eviction or filtering removes only markers whose rows are no longer resident. The active marker is the latest checkpoint at or before the first visible row; when the viewport begins before every loaded checkpoint, the first loaded checkpoint is the bounded fallback.

Each user and response excerpt is independently normalized to one visual line and bounded to 160 Unicode scalar values. The preview card is at most 360 px wide and never wider than the viewport minus a 32 px gutter. Both sections wrap and clamp to three lines, so long unbroken tokens cannot become a window- wide tooltip strip. The accessibility description includes both excerpts when the response exists.

Resident response pairing is deliberately source-specific:

  • Native Chat uses the last non-empty assistant message before the next user message.
  • Codex uses the last non-empty authoritative AgentFinal in the same turn. Commentary, commands, tools, developer activity, reasoning, other turns, and provisional finals are excluded.
  • DSH uses the last non-empty assistant/message before the next user row and enforces the same turn when a user turn ID exists. assistant/chunk, model/start, and model/end rows are excluded.

If no matching resident response exists, the agent section is omitted. The UI does not fabricate a response and does not load history on hover or focus.

Codex omitted-history truthfulness

An omitted-history timeline row can represent three distinct states: another page can load, the newest 500-item resident cap is reached, or the reduced- fidelity server cannot page older history. The checkpoint rail now projects an unnumbered history affordance only for the first state.

Activating the affordance cancels motion and jumps to the existing history row. It does not enqueue CodexRuntimeCommand, consume a cursor, or mutate mirror freshness. The user must still activate LOAD OLDER HISTORY explicitly.

Source identity and asset provenance

The header now uses one shared native icon-tab primitive:

  • EXEPERT uses original product artwork under assets/activity;
  • Codex and DeepSeek use locally vendored, adapted theSVG source marks;
  • the native asset source embeds every mark into the executable;
  • runtime hotlinking and network loading are absent;
  • selected, hover, focus, keyboard, and accessibility states remain explicit; and
  • the measured stage width controls whether the selected source label is visible.

THIRD_PARTY_NOTICES.md records the source URLs, retrieval metadata, original response hashes, adapted bundled-file hashes, presentation-only modifications, trademark ownership, and the unresolved legal/brand review boundary. The source endpoints are mutable, so the recorded hashes pin the exact retrieved inputs used by this delivery.

Privacy, persistence, and ownership boundaries

  • Activity expansion, auto-scroll state, checkpoint focus, excerpts, paired previews, and source-tab focus handles remain process-local.
  • Transcript and search content is not added to settings, diagnostics, or serialized state.
  • Checkpoint rails consume only loaded/resident rows and never own cursors.
  • Codex App Server remains the source of truth for persisted Codex history.
  • DSH remains a separate canonical source with its existing local store.
  • The existing 500-item Codex cap, lazy paging/search, mirror ownership, mutation firewall, source-copy semantics, and raw-reasoning exclusion remain unchanged.
  • No database, migration, transport, external protocol or product API, settings schema, or dependency changed. New Rust helpers and constants stay within the existing native desktop UI module boundary.

Accessibility contract

  • Activity controls expose stable item-qualified IDs, accurate expanded state, expand/collapse labels, focus styling, and directional chevrons.
  • Each ordinary user marker is a button named Jump to user message N with a bounded paired description and stable row-qualified ID.
  • An ordinary checkpoint rail is a navigation region named User messages. The history-only Codex rail instead uses Older user messages, and its unnumbered button explains that older checkpoints are outside loaded history.
  • Hover and keyboard focus use the same structured preview content.
  • Source tabs retain chat-source-exepert, chat-source-codex, and chat-source-dsh, plus ARIA selection and stable accessible names.
  • Enter and Space switch an inactive source; standard focus traversal remains native GPUI behavior.

Verification record

The final source candidate was checked with:

cd desktop
cargo +1.96.0-x86_64-pc-windows-msvc fmt --all -- --check
cargo +1.96.0-x86_64-pc-windows-msvc test --workspace --all-targets --locked --target x86_64-pc-windows-msvc
cargo +1.96.0-x86_64-pc-windows-msvc clippy --workspace --all-targets --locked --target x86_64-pc-windows-msvc -- -D warnings
cargo +1.96.0-x86_64-pc-windows-msvc build --package exepert-desktop --target x86_64-pc-windows-msvc --release --locked
cargo +1.96.0-x86_64-pc-windows-msvc test --package exepert-desktop --lib --target x86_64-pc-windows-msvc --locked -- --ignored --test-threads=1
cargo +1.96.0-x86_64-pc-windows-msvc test --package exepert-desktop --test codex_timeline_render --target x86_64-pc-windows-msvc --locked -- --ignored --test-threads=1
cd ..
pnpm.cmd --dir docs-site exec docusaurus build
git diff --check

Observed results on 2026-09-02:

  • the complete locked all-target workspace suite passed; its library portion reported 453 passed and two intentionally ignored native harnesses, and every enabled integration suite passed;
  • all Codex UX contracts passed, including authoritative pairing, truthful omitted-history behavior, rail remeasurement, responsive tabs, and paired accessibility copy;
  • all four opt-in Windows GPUI harnesses passed explicitly and serially: bounded Codex folding geometry, independent transcript/checkpoint virtualization, frame-driven auto-scroll, and narrow-window paired preview;
  • strict workspace Clippy passed with plain -D warnings and no allowlist;
  • Rustfmt and git diff --check passed;
  • the optimized Windows release build passed and produced desktop/target/x86_64-pc-windows-msvc/release/exepert-desktop.exe (39,141,376 bytes); and
  • the Docusaurus production build passed with the delivery page and sidebar entry.

The first increment's Windows acceptance exercised folding, expansion, auto-scroll activation/cancellation, and checkpoint navigation. The refinement increment adds deterministic source-pairing tests and a native narrow-viewport preview harness. A fresh physical mouse/keyboard pass over the final compact card and source-tab visuals remains a human interaction check, not an automated claim.

Known follow-up edges

Two pre-existing limits are recorded in _bmad-output/implementation-artifacts/deferred-work.md:

  1. The no-new-dependencies boundary retains a handcrafted truncation helper. It preserves UTF-8 and common combining, emoji, joiner, variation-selector, and flag sequences, but does not implement every Unicode grapheme-extension class.
  2. Ordinary desktop harnesses retain fewer than 80 realized checkpoint rows. An unusually tall transcript viewport around 2,500 px may realize 80 or more 32 px markers because of the rail's 64 px overdraw.

Neither follow-up changes paging, persistence, source truth, or normal desktop interaction behavior.

Repository change inventory

This is the exhaustive path inventory relative to baseline commit b356c45. At documentation finalization Git reported exactly 23 changed paths: 7 additions, 16 modifications, and no deletions or renames. Generated Cargo and Docusaurus output remains ignored and is not part of the commit.

Root records and implementation specifications

M THIRD_PARTY_NOTICES.md
M _bmad-output/implementation-artifacts/deferred-work.md
A _bmad-output/implementation-artifacts/spec-transcript-checkpoint-source-navigation-refinement.md
A _bmad-output/implementation-artifacts/spec-transcript-folding-navigation.md

Native desktop source and embedded assets

A desktop/exepert-desktop/assets/activity/chat-chevron-right.svg
A desktop/exepert-desktop/assets/activity/source-exepert.svg
A desktop/exepert-desktop/assets/third_party/thesvg/codex.svg
A desktop/exepert-desktop/assets/third_party/thesvg/deepseek.svg
M desktop/exepert-desktop/src/app.rs
M desktop/exepert-desktop/src/ui/activity.rs
M desktop/exepert-desktop/src/ui/chat.rs
M desktop/exepert-desktop/src/ui/codex_transcript.rs
M desktop/exepert-desktop/src/ui/dsh_transcript.rs
M desktop/exepert-desktop/src/ui/native_chat_transcript.rs
M desktop/exepert-desktop/src/ui/transcript.rs

Native desktop tests and contracts

M desktop/exepert-desktop/tests/chat_presentation_ux_contract.rs
M desktop/exepert-desktop/tests/codex_timeline_render.rs
M desktop/exepert-desktop/tests/codex_ux_contract.rs
M desktop/exepert-desktop/tests/emoji_ux_contract.rs

Documentation and navigation

A docs-site/docs/architecture/native-transcript-navigation-delivery.md
M docs-site/docs/architecture/native-codex-client.md
M docs-site/docs/frontend-modules/native-desktop-chat.md
M docs-site/sidebars.ts

Maintainer reading order

  1. Read the two completed implementation specifications under _bmad-output/implementation-artifacts/ for the approved intent and review trails.
  2. Review desktop/exepert-desktop/src/ui/transcript.rs for the shared motion, checkpoint, preview, and stable-bookmark engine.
  3. Review desktop/exepert-desktop/src/app.rs for source-specific projection, hard Codex activity rendering, and responsive source-tab composition.
  4. Compare the Native, Codex, and DSH transcript views for their thin bindings over the shared state.
  5. Review THIRD_PARTY_NOTICES.md and the source-selector asset tests before distributing the two third-party marks.
  6. Read the contract tests and native harnesses before changing row identity, checkpoint realization, motion cancellation, or accessibility semantics.

Git delivery boundary

The feature branch is codex/transcript-navigation-refinement. The commit containing this document is the delivery commit. No deployment or binary distribution is part of the GitHub merge; the optimized executable remains a local build artifact.