Skip to content

fix(mobile): reconcile authoritative terminal frames - #197

Draft
Lint111 wants to merge 5 commits into
Ark0N:masterfrom
Lint111:agent/split-authoritative-terminal-frame
Draft

fix(mobile): reconcile authoritative terminal frames#197
Lint111 wants to merge 5 commits into
Ark0N:masterfrom
Lint111:agent/split-authoritative-terminal-frame

Conversation

@Lint111

@Lint111 Lint111 commented Jul 29, 2026

Copy link
Copy Markdown

Summary

  • Preserve the last painted xterm rows while a phone keyboard or session transition resizes the terminal.
  • Reconcile Codex with a bounded 128KB mux-visible pane after keyboard resize, WebSocket attachment, or foreground dialogue submission.
  • Hold live SSE/WS output during replacement and replay only bytes after the snapshot cursor, including cursor-crossing synchronized updates.
  • Coalesce overlapping transitions, abort superseded work, and bound a stalled snapshot request to five seconds.
  • Re-anchor pending local input after the authoritative pane paints without clearing existing xterm scrollback.

Motivation

Codex can emit several resize redraws while the mobile visual viewport changes. xterm may briefly expose an older pane, blank rows, or overlapping history before the TUI reaches its final size. A visual cover removes the intermediate paint, while cursor-qualified reconciliation makes the frame behind that cover current before it is revealed.

Dialogue selection uses the same path because a prompt can be replaced immediately after Enter or a terminal mouse selection. Input is still dispatched once; the frame capture is asynchronous and cannot block delivery.

Commit Scope

This branch is a focused terminal stack:

  1. 92dbe64 retains buffer-load ownership during replay (also carried by fix(terminal): preserve replay and history ownership #193).
  2. 45f425d coalesces keyboard viewport settling (patch-equivalent to fix(mobile): coalesce keyboard viewport settling #194).
  3. cc37643 drains deferred terminal output without a later wake event (patch-equivalent to fix(terminal): drain deferred output without a wake event #190).
  4. 7bfee75 adds the inert resize-frame cover.
  5. fddd53a adds authoritative cursor reconciliation and its tests.

It does not include the mobile navigation pad, terminal tap policy, repository viewer, shutdown endpoint, input controller, or other features from #173.

Dependencies

Merge the terminal contracts before this PR:

  1. feat(terminal): add bounded snapshot and history streaming #189 supplies bounded streamed pane snapshots plus SSE/WS cursor metadata.
  2. fix(terminal): let the active viewport reclaim PTY sizing #191 supplies explicit viewport ownership and the takeControl / refit resize options.
  3. fix(terminal): drain deferred output without a wake event #190, fix(terminal): preserve replay and history ownership #193, and fix(mobile): coalesce keyboard viewport settling #194 supply the prerequisite client commits already visible in this branch.

An integration rehearsal combined #189, #191, and this branch. Two overlapping merge blocks are additive:

  • Keep stream handoff (t: "h") and viewport takeover (a: true) in ws-routes.ts, with one shared announcedViewport declaration beside announced rows/columns.
  • Keep _requestTerminalFrameReconcile() in mobile-handlers.js instead of the older direct sendResize() call.

The reconciled tree built successfully and passed the joint route and browser suites.

Failure Behavior

  • Runs only for touch-device, non-shell terminal sessions.
  • Publishes a replacement only when the response is mux-visible, non-empty, and has a valid stream cursor.
  • A stale session, superseding request, fetch failure, timeout, or cancellation releases the buffer gate and flushes queued live output.
  • The cover is pointer-transparent and has bounded expiry; dialogue controls and terminal input remain interactive.

Verification

  • npm run build
  • npm run typecheck
  • npm run lint
  • npm run check:frontend-syntax
  • npm run check:public-assets
  • npm run format:check
  • Focused unit suites: 25 passed
  • Focused Chromium suites: 4 passed
  • Dependency rehearsal: 158 server/client contract tests, 3 viewport browser tests, and 3 reconciliation browser tests passed
  • Isolated npm run test:ci with test: isolate runtime state and PTY integration #175 fixture safeguards: 189 files passed, 1 skipped; 3,817 tests passed, 12 skipped

Related

Extracted from the terminal transition portion of #173 in response to the maintainer's scope review.

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