* feat(mobile): give every text input the chat composer's look
Adds shared MessageBox, TextField and ComposerSendButton built from the
composer's own styles, and moves chat, form, search, Tasks, PR, review and
commit inputs onto them. The commit message becomes multi-line, every input
is 16pt (no page zoom on focus), and focus rings are gone. The terminal and
browser typing docks are unchanged.
* feat(mobile): rebuild the terminal dock around Keys and Message modes
Agent tabs open in Message mode, where you write in the chat composer and
Send types it into the terminal. Shell tabs open in Keys mode, where each
letter goes straight to the terminal through the live field. A pick made on
an agent tab lasts until the agent quits. The shell/agent rule is the one
keyboard dismissal already used, now shared.
The key row carries sticky ctrl, alt and shift (tap for the next key,
double tap to lock) and one arrow pad (tap a side, or hold and drag to
repeat through the existing held-key repeat). Paste, attachments, the
display width, the remaining keys and custom keys move to a ⋯ sheet. Return
in the composer adds a line; Send sends.
* fix(mobile): read arrow-pad taps from the pad and keep every key reachable from ⋯
A touch on a chevron made the icon the touch target, so the side was
measured against the icon's box and most taps read as left. The ⋯ sheet
now leaves out only the keys the current row shows, so agent tabs get Tab
and shell tabs get Shift+Tab and Enter back.
* fix(mobile): keep the last changed files clear of a growing commit box
The file list's bottom inset was a fixed 196 pt, so a commit message several lines long hid the last rows behind the commit bar. The inset now follows the bar's measured height.
* test(mobile): give the file list test its bottom inset
* fix(mobile): retain editor styling when switching color schemes
* test(mobile): fit theme-switch harness hooks under the file line cap
---------
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
* fix(mobile): keep table-cell and list-item line breaks on their own source line
Table cells and list items save line breaks as <br /> (and sibling P/DIV
blocks inside an item as breaks), and reopen attribute-free <br> tokens
as breaks, so Shift+Enter or Enter no longer splits a row or ends a list.
Typed '<br>' text gets only its '<' entity-escaped, raw text newlines
become spaces, and browser caret placeholder breaks are dropped (a cell
that holds only a placeholder saves empty; a cleared item keeps a <br />
so its marker still parses).
* fix(mobile): keep fenced code blocks inside Markdown list items
Indented fences under a list item (README steps such as
'1. Install:' followed by an indented bash fence) now read as a code
block inside the item and save back under the item's continuation
indent. Only items whose continuation holds a fence change; headings,
quotes, rules and tables after the fence end the item and read as
before. Top-level and list code blocks share one PRE writer, blank
separator lines are not indented, and a fence needs no blank line
beside it so tight items stay tight.
* fix(mobile): keep caret code blocks out of the paragraph they follow
Code block with a collapsed caret after text in its block ran native
insertHTML, which merged the PRE into that paragraph as prose. Prepend
a <br> only when content precedes the caret, so block-start, empty-line
and empty-document insertions stay as they were.
* fix(mobile): keep authored runs of trailing table-cell breaks
* fix(mobile): use template literal for list code-fence probe
---------
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
* fix(mobile): preserve literal code through rich Markdown edits
* fix(mobile): preserve inline code containing backticks
* Preserve adjacent inline-code text when saving mobile Markdown
* Preserve quote paragraphs and blocks in mobile Markdown
* fix(mobile): preserve selected text when creating code blocks
* test(mobile): choose native history shortcut from browser host
* Preserve paragraph-owned mobile code blocks when saving
* Preserve code selected inside mobile headings after saving
* fix(mobile): keep code serialization space-normalized and trim review tests
- Inline code and code blocks keep turning browser-created NBSPs into spaces;
only the reader-side entity fix is needed for literal code.
- Inline code line breaks save as spaces so table rows and headings stay intact.
- Code blocks keep trimming trailing newlines left by placeholder <br>s.
- Heading- and paragraph-owned code blocks join adjacent inline code runs.
- Empty nested quotes reopen as a plain empty paragraph.
- Trim synthetic and behavior-locking tests.
* fix(mobile): keep quoted text literal when block reading would rewrite it
Quoted list continuations and lazy lines were restructured on save because the list reader drops them; reopen quote blocks only when they save the source or the same bytes as the literal paragraph.
* test(mobile): use template literal for saved code-block markdown
---------
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
* fix(mobile): show live input caret and preserve selection edits
Display the existing input directly so its native caret shows. Accessory
Backspace/Delete edit at the field's caret, read from the input when pressed,
so edits that keep the caret (IME composition) still delete, and the caret is
restored for subsequent typing.
Port and adapt community PR #28294 to the current command dock.
Co-authored-by: Kyino <kyino1025@gmail.com>
* fix(mobile): keep live input caret keys local and the dock height fixed
Hardware Left/Right/Home/End moved both the visible field caret and the
PTY cursor, so the mirror erased at the wrong place. With field text they
now move only the field caret, like Backspace and Delete; Right/End at the
field end still reach the PTY so shells can accept an autosuggestion. On
Android the key binding lets plain caret keys through to that decision
instead of sending them to the PTY. The dictation and upload status covers
the field instead of adding a row, so starting or stopping either no longer
resizes the terminal.
* test(mobile): annotate the DOM field cast in the accessory input test
* chore(mobile): allowlist the live input field strings for localization coverage
---------
Co-authored-by: Kyino <kyino1025@gmail.com>
Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
* fix(mobile): restore lifecycle-safe terminal accessory repeat
The selection hook replaced the established repeat controller with unbounded timers, allowing held keys to cross terminal/client changes. Reintegrate the existing pinned sender, lifecycle cancellation and backpressure.
* test(mobile): stop held terminal input after refusal or disconnect
* test(mobile): give accessory-repeat harnesses the PTY modes and focus hook main now reads
* fix(mobile): stop a held key when its strip unmounts and repeat through the current live-input mode
* fix(mobile): type the accessory repeat sender's input
* refactor(mobile): read app state live in the accessory repeat gate
* test(mobile): pin the key bar's held press to the repeat controller's first send
---------
Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
mobile/ is a separate pnpm project, so the root pnpm install leaves
mobile/node_modules empty and pnpm build failed in build:mobile-web with
hundreds of unexplained esbuild "Could not resolve" errors.
build-mobile-web-app-bundle now checks for mobile/node_modules first and
exits with the one command that fixes it. The probe path is shared with
the bundle tests' dependency check. CONTRIBUTING documents the install in
Local Setup and points "Before Opening a PR" at it.
Fixes#24324
Co-authored-by: Neil <neil@stably.ai>
* feat(mobile): light and dark themes with desktop's palettes
Settings → Appearance offers System, Light and Dark. The shell passes the
resolved scheme to over-the-air pages in its init frame.
Fixes#22184
* fix(mobile): draw your chat messages in desktop's user bubble
Desktop uses a faint surface with a hairline border in both themes; the inverted fill went black in light.
* test(mobile): re-measure the page script sweep after the shared theme hooks
Every route now imports the theme hooks while the entry does not, so they emit one shared script (96 for the tree). Re-swept every route prefix; the worst route step is now 15.
* test(mobile): read themed stylesheets in the text-input font-size census
The census only unwrapped StyleSheet.create({...}); inputs styled through themedStyleSheet(() => ({...})) came back unread.
* test: remove low-value inventories, passthroughs and redundant cases
* style: format test suites after pruning redundant cases
* test: remove obsolete workflow and flaky-test references
* test: prune deleted builder test from Windows shim allowlist
---------
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
* test(mobile-web): act on the HTML preview frame only once the browser routes input into it
Chromium runs the sandboxed preview frame in its own process. The rig decided an arm was
ready once the artifact had parsed, but the embedder can still be showing the frame's white
before its surface is composited, and still keep pointer input over the frame for itself
until it holds the frame's hit-test region. A click in that window landed on the
embedder's <iframe>, Playwright reported success, and the arm waited for a navigation
that never came (or read white as pixelBefore).
The rig now waits for the artifact's paint before reading pixelBefore, and before acting
moves the pointer over the frame until the embedder stops receiving it.
* test(mobile-web): name the arm in the input-routing timeout and trim history comments
* test(mobile-web): click the drawer chip once it is actionable, and honour the wait timeouts
* test(mobile-web): say why the drawer trial click stays, and report a failed open with page errors
* fix(mobile): preserve agent icons across stacked routes and tab updates
Closes#31939
* fix(renderer): address review feedback on mobile agent icon stability
* fix(renderer): fall back to customTitle when saved leafTitle is blank
* Keep mobile agent icons painted across retained routes
Use instance-specific OMP gradients and preserve bundled icon fallback during web image reload failures. Add a real mobile-web route-retention pixel regression.
Adapted from zhangxaochen’s scoped rendering fixes in #31948; unproven session equality and title changes are excluded.
Co-authored-by: zhangxaochen <zhangxaochen@163.com>
---------
Co-authored-by: Neil <neil@stably.ai>