Skip to main content

Native Chat and Codex delivery record

This record describes the native desktop changes developed after baseline commit de8dbd2 (feat(desktop): ship native multimodal chat). It is the review and release map for the compact EXEPERT Chat refinements, the Experimental Codex source, read-only task mirroring, rich transcript rendering, and the virtualized smooth-scrolling upgrade.

The implementation remains native Rust and GPUI. It does not add Electron, React, a WebView, a private Codex Desktop bridge, durable Codex transcript storage, or a new EXEPERT backend contract.

Delivered experience

EXEPERT Chat surface

The existing EXEPERT/Supabase Chat source now provides:

  • a compact content-driven composer with a 20 px local radius, subtle outline, 8 px bottom elevation gap, and no full-width shell divider;
  • a one-row minimum textarea that grows to responsive 8, 10, or 12-row caps before scrolling internally;
  • a populated-draft resize freeze so window changes cannot reset selection, undo history, or draft geometry;
  • a left-aligned Tools and attachments menu containing only implemented attachment and saved-prompt actions;
  • a compact provider-aware model selector immediately before Send or Stop;
  • opaque, deferred model and prompt surfaces that cannot show transcript lines through their background;
  • flat assistant responses, compact right-aligned user bubbles, response-local feedback, and header-local New Chat;
  • initial-only prompt suggestions and state-aware Send, Stop, Retry, image, and feedback controls;
  • native Tab traversal, focus-visible rings, semantic log/article/status/alert roles, and readable secondary copy; and
  • threshold-aware transcript following with an explicit latest-response action when the reader is away from the bottom.

These refinements preserve image limits, request readiness, verified model routing, saved-prompt authentication, local transcript privacy, feedback, brain grounding, and every established chat-* inspector ID.

Experimental Codex source

The Chat workspace now also contains an isolated Codex Experimental source that owns one external Codex App Server process. The client:

  • requires exactly codex-cli 0.149.1 and launches its native executable directly rather than through a command shell;
  • initializes the official stdio App Server protocol with raw-reasoning text disabled;
  • owns independent task, transcript, composer, attachment, model, effort, approval, focus, scroll, and diagnostic state;
  • supports new tasks, acknowledged Take Over, Fork, steering, interruption, detach, typed approvals, and bounded task recovery;
  • keeps no Codex message, draft, attachment contents, credential, approval grant, or raw protocol payload in EXEPERT persistence or Supabase; and
  • uses a Windows kill-on-close Job Object so the owned App Server and its descendants cannot outlive the desktop unintentionally.

The generated 0.149.1 stable and experimental JSON Schema bundles are committed with integrity manifests. The prior 0.125.0 bundle remains as historical compatibility evidence; it is not accepted by the runtime.

Automatic discovery and read-only mirror

Stored tasks from CLI, VS Code, and App Server sources are reconciled in recency order. Discovery polls every second while Codex Chat is visible and every five seconds in the background, with non-overlap, atomic pagination, 30-second failure backoff, and a full manual Refresh path.

One stored task can be mirrored without taking control. Mirror mode:

  • reads only persisted task metadata and a bounded 500-item transcript;
  • prefers item pagination, falls back to turn pagination, and finally uses a capped thread snapshot with an explicit reduced-fidelity warning;
  • reports SYNCING, MIRRORING, STALE, or UNAVAILABLE independently from the App Server's ownership status;
  • disables turns, steering, attachments, approvals, interruption, and model mutation; and
  • remains process-local and is cleared on Stop Mirror, task/source changes, exit, or recovery.

Take Over and Fork retain the read-only view until the matching App Server acknowledgement succeeds. Automatic mirror polling never calls thread/resume or another mutating method.

Transcript rendering and performance

Final Codex answers and commentary use GPUI's native selectable Markdown view, keyed by server turn and item identity. User messages, readable reasoning summaries, commands, output, file changes, and developer activity remain literal text. Links use GPUI's normal URL handler, while remote Markdown images use the normal image loader without Codex credentials or task metadata. Copy Visible Transcript continues to copy the verbatim server source rather than reconstructing rendered Markdown.

The transcript is a cached child CodexTranscriptView, not a full-tree scroll container. Its variable-height ListState realizes visible rows plus 512 px overdraw while retaining the 500-item logical cap. Stable row keys and process-local bookmarks preserve the currently read row, offset, focus, and tail-follow state through:

  • task switching;
  • activity filtering;
  • bounded prefix removal;
  • Markdown height changes;
  • mirror updates; and
  • pending-submission or approval reconciliation.

The vendored GPUI list keeps its existing immediate wheel behavior by default and adds one opt-out for the Codex child. Pixel-precise touchpad input stays direct. Discrete line-wheel input uses a bounded 140 ms ease_out_quint glide, retargets same-direction input up to one viewport, cancels on reversal or explicit navigation, clamps without bounce, and becomes immediate when reduced motion is enabled.

Polling and repaint suppression

Ordered discovery snapshots and normalized mirror presentation snapshots use process-local SHA-256 fingerprints. Identical results after the initial result do not emit duplicate UI events. Recovery from STALE or UNAVAILABLE still emits even when restored content is identical.

Reducer applications return one of three outcomes:

OutcomeUI work
NoopNo root or transcript notification
MetadataOnlyRefresh shared task/runtime presentation
TranscriptChangedReconcile the transcript child and shared task metadata

This removes the former unconditional one-second repaint without changing poll cadence, freshness, atomic pagination, stale-epoch rejection, or manual Refresh semantics.

Source inventory

PathDelivered responsibility
desktop/exepert-desktop/src/app.rsChat source selection, native composer and transcript integration, Codex task UI, approvals, accessibility, event routing, and child-view synchronization
desktop/exepert-desktop/src/ui/chat.rsChat-local spacing, radius, focus, popup, model-trigger, progress, and responsive-composer primitives
desktop/exepert-desktop/src/ui/activity.rsExplicit Claude/Anthropic and OpenAI/GPT/Codex provider-logo mapping with a generic fallback
desktop/exepert-desktop/src/ui/codex.rsCodex timeline presentation primitives and width contracts
desktop/exepert-desktop/src/ui/codex_transcript.rsVirtual rows, bookmarks, child-only repainting, tail follow, remeasurement, and adaptive scrolling
desktop/exepert-desktop/src/codex/Launcher, Windows ownership, JSONL transport, protocol DTOs, runtime, reducer, settings, and diagnostics
desktop/vendor/gpui/src/elements/list.rsDefault-compatible with_wheel_scroll_enabled(false) support and variable-height realization coverage
desktop/exepert-desktop/schemas/codex-app-server/Historical 0.125.0 evidence and exact 0.149.1 stable/experimental schema bundles with manifests
desktop/exepert-desktop/tests/Chat/Codex source contracts, replay fixtures, reducer/runtime behavior, width proof, and virtualization harness
desktop/{Cargo.toml,Cargo.lock} and desktop/exepert-desktop/Cargo.tomlWindows Job/process APIs required by the owned App Server lifecycle
docs-site/docs/frontend-modules/native-desktop-chat.mdShared native Chat UX, image, accessibility, popup, and verification contracts
docs-site/docs/architecture/native-codex-client.mdCodex topology, protocol, task/mirror lifecycle, trust boundary, recovery, and upgrade runbook

The completed implementation specifications and deferred accessibility follow-up notes live under _bmad-output/implementation-artifacts/. They record the accepted requirements and review history; the two architecture pages above are the maintained operational documentation.

Compatibility and privacy invariants

  • EXEPERT Chat and Codex remain separate state and transport domains.
  • Existing EXEPERT Chat, image-input, Supabase, 9Router, persistence, feedback, and affect contracts are unchanged by the Codex source.
  • Codex accepts exactly 0.149.1; unknown versions fail closed with setup guidance.
  • Experimental App Server methods are restricted to the read-only persisted item and turn pagination boundary.
  • Raw reasoning text is discarded before UI state and diagnostics.
  • Codex transcript content, drafts, image bytes, credentials, approvals, mirror cursors, and raw frames are never written to EXEPERT settings or Supabase.
  • Diagnostics retain bounded allowlisted metadata and redact tokens, secrets, authorization headers, ANSI controls, and credential-shaped values.
  • The 500-row transcript limit and bounded item-output limits remain enforced.
  • Benchmark and renderer-probe modes do not initialize Chat or Codex state.

Build and verification record

The completed local validation used the pinned Windows toolchain:

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 --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 `
-A clippy::too_many_arguments -A clippy::needless_return `
-A clippy::collapsible_if
cargo +1.96.0-x86_64-pc-windows-msvc build --workspace --release --locked --target x86_64-pc-windows-msvc

The locked workspace suite, Chat/Codex contracts, replay tests, strict Clippy with the documented existing allowlist, Rustfmt, and Windows release build all passed. The two ignored native renderer harnesses also passed serially:

cargo +1.96.0-x86_64-pc-windows-msvc test --locked --target x86_64-pc-windows-msvc `
--test codex_timeline_render codex_timeline_native_bounds_prevent_glyph_columns `
-- --ignored --exact --test-threads=1

cargo +1.96.0-x86_64-pc-windows-msvc test --locked --target x86_64-pc-windows-msvc `
--test codex_timeline_render codex_virtual_transcript_realizes_overdraw_in_child_view `
-- --ignored --exact --test-threads=1

Documentation was built directly, without requiring calendar regeneration:

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

A native release smoke at approximately 1280×720 mirrored an existing task, rendered rich content at full transcript width, scrolled the virtual list, and preserved the reading position across the next foreground mirror poll. It did not create a paid turn or invoke Take Over, Fork, approval, or another mutating Codex action.

Physical precision-touchpad feel, the operating-system reduced-motion setting, remote Markdown media, and the exact 1024×640 and 1920×1009 layouts remain manual release checks. Automated source contracts and native renderer harnesses must not be represented as substitutes for those interactions.

Build and launch

Install the exact external Codex version before using the Experimental source:

npm install -g @openai/codex@0.149.1
codex --version

Build and launch the target-specific executable:

cd desktop
cargo +1.96.0-x86_64-pc-windows-msvc build --workspace --release --locked --target x86_64-pc-windows-msvc
.\target\x86_64-pc-windows-msvc\release\exepert-desktop.exe

Suggested review order

  1. Read Native desktop Chat for user-visible state and accessibility contracts.
  2. Read Native Codex live client for process, protocol, privacy, mirror, and recovery boundaries.
  3. Review src/codex/state.rs and src/codex/runtime.rs before the GPUI integration in src/app.rs.
  4. Review ui/codex_transcript.rs, the vendored list opt-out, and the native renderer harness together.
  5. Inspect the schema manifests and deterministic replay fixtures before accepting any future Codex version change.