Commit Graph
360 Commits
Author SHA1 Message Date
Neil 7d141d491f refactor(mobile): group notification delivery and lifecycle owners (#41290) 2026-11-11 15:46:31 -08:00
NeilandKelvin Amoaba 5d61e00c6d build(mobile): upgrade to Expo SDK 58 and React Native 0.88 (#37935)
* build(mobile): upgrade to Expo SDK 58 and React Native 0.88

Expo 58 drops Zod from @expo/cli, which clears the last Zod 3 advisory
(GHSA-mrhx-c7xc-m3w5) in mobile along with its local patch and override.

- Expo 55 -> 58, React Native 0.83 -> 0.88, React 19.3, gesture-handler 3,
  webview 14, reanimated 4.7, worklets 0.13 (SDK 58 bundled versions,
  pinned below today's batch to respect minimumReleaseAge).
- Port the react-native and react-native-webview patches unchanged; drop
  expo-constants, expo-notifications, @expo/cli, expo-router, zod and
  query-string patches plus the zod/query-string/xcode>uuid overrides,
  which upstream fixed or no longer need.
- iOS minimum rises to 16.4 (Expo 58 / RN 0.88 requirement).
- Migrate to RN 0.88 strict types: instance ref types, NamedStyles,
  AppState.currentState, list header/footer nulls.
- Replace removed runtime APIs: InteractionManager -> idle callback with a
  macrotask fallback; StyleSheet.absoluteFillObject -> absoluteFill;
  FileHandle.readBytes -> readBytesSync (it became async).
- Resolve react-native/asset-registry for shared assets in Metro and alias
  the old registry path for react-native-svg in the desktop mobile-web bundle.
- Reduce the iOS scene plugin to the reconnect override; Expo 58's template
  now ships the scene delegate itself.

* fix(mobile): bridge react-native-svg web imports and libsodium runtime for RN 0.88

- Share react-native-svg web shims between the mobile-web build and its render
  checks: map the old asset-registry path to react-native-web's registry and stub
  the Android-only touch-sound TurboModule.
- Patch react-native-libsodium 1.7.0 to read the JSI runtime from the bridge proxy;
  RN 0.88 removed RCTCxxBridge.runtime.

* fix(mobile): use Expo 58's legacy promise resolver for audio permissions

* fix(mobile): skip null handles in the RPC recording timer shims for RN 0.88 types

* style(mobile): format MobilePRSidebar after rebase

* fix(mobile): name RN 0.88 text input refs for declarations; allow queued back in stack render check

- Type text input refs with an exported interface so declaration emit can name hook results
  (RN 0.88 aliases TextInputInstance to an unexported class).
- Expo Router 58 drains back() after a commit; check the interrupted push's exit from the
  frame it starts, bounded to three frames of lag.

* chore(mobile): justify the text input handle interface for React Doctor

* chore(mobile): use a nameable intersection alias for text input refs

* fix(mobile): use sync expo-file-system writes, copies and moves on Expo 58

Expo 58 made File.write/copy/move and FileHandle.writeBytes return promises.
Our callers never awaited them, so failures escaped their try/catch and the
store's tmp-then-move and PDF writes could race their close or rename.

* build(mobile): raise the page bundle budget to 10 MiB for Expo 58

Expo 58 adds about 310 KB to the page: expo-router (+258 KB, now carrying
React Navigation, net about +110 KB) and Reanimated 4.7 (+152 KB). Main had
85 KB of headroom left. 10 MiB still stays within the 10 MiB per-asset contract.

* fix(mobile): drop the window-metrics seed RN 0.88 removed from Android

RN 0.88 no longer holds window metrics: DeviceInfoModule reads the activity's
WindowMetrics on demand and setWindowDisplayMetrics is gone, so MainActivity
no longer compiled. Layout scale still comes from the screen metrics we reseed.

---------

Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-11-11 23:30:02 +00:00
Neil dc9a7abfc1 refactor(mobile): group host catalog credentials and descriptors (#40739)
* refactor(mobile): group host catalog credentials descriptors and connection history

* refactor(mobile): import RPC sender and result types from defining owners

* refactor(mobile): colocate push delivery with registration operations

* refactor(mobile): point push recordings at delivery owner
2026-11-10 02:52:14 -08:00
Kelvin Amoaba bca56f7776 feat(mobile): keep dictating after leaving the session, with a floating pill (#40421)
* feat(mobile): keep dictating after leaving the session, with a floating pill

* feat(mobile): translate the dictation pill and its toasts

* fix(mobile): type away words without claiming the terminal, and keep the pill above screens

* fix(mobile): float the pill above bottom bars, reopen the owner's own screen, and tell a refused start wherever you are

* fix(mobile): float the dictation pill above the source control bar

* fix(mobile): keep pill state out of the host context and reopen the starting screen first

* refactor(mobile): subscribe the pill only while it shows and trim the session dictation hook

* fix(mobile): key bar clearances by symbol
2026-11-09 17:52:00 +00:00
Kelvin Amoaba 8b1c394a41 perf(mobile): open Home with last-known workspaces and counts (#40129)
* perf(mobile): open Home with last-known workspaces and counts

* fix(mobile): keep disconnected desktops on Home and judge agents by the client's connect time

* fix(mobile): store the seeded Home counts before removing the old snapshot

* fix(mobile): floor router reads after failures, catch up reads that span a stream reopen, seed the wide host list from Home

* fix(mobile): keep the old Home snapshot until the store can take it, and never re-date stored totals

* perf(mobile): key Home's counts in the host list module so the page boot never loads Home's code

* test(mobile): type the Home catalog adapter's modules with type imports

* perf(mobile): read Home's stored rows in one batch beside the host list, and keep mark-read a delta read

* perf(mobile): paint Home's desktop rows without waiting for the stored counts

* perf(mobile): restore Home's stored rows after the desktop list paints, from its host ids

* perf(mobile): read Home's counts on the connected edge itself, not a render later
2026-11-09 14:06:15 +00:00
Brennan Benson 4fc4d792be Show folder workspace Source Control on the phone (#39999)
* feat(mobile): show folder workspace Source Control on the phone

A folder workspace now has Source Control on the phone: one row per attached
worktree (repo, name, branch, ahead/behind, change count), read from the host
list's own lineage projection and each worktree's git.status. Tapping a row
opens that worktree's existing Source Control in place; Back returns to the list.

* fix(mobile): folder Source Control routing, back, hidden reads and failure states

- A desktop worktree under a server's folder is listed and opens with desktop routing and gates.
- A child opened in the dock gets Back to the folder list beside Close.
- Rows and the catalog stop reading while the screen is covered, as the single-worktree screen does.
- Offline, failed and missing-folder states; rows whose status can't be read say Unavailable.
- Server rows poll like the host list; branch shown without refs/heads/.
- Perf contract: git.status reads per signal at N and 10N rows.

* perf(mobile): folder Source Control reads summaries and rebuilds only on lineage changes

- Rows read a status summary without per-file line stats; relayed servers' rows open no desktop event stream.
- Membership resolves over a projection of lineage and label fields, so agent and terminal churn rebuilds nothing.
- A row whose re-read failed or whose host reported readError shows Unavailable.
- A connection still coming up shows loading, not offline.
- Perf contracts at N/10N rows and H/10H catalog rows.

* perf(mobile): folder membership keys on lineage only; child status reads update the folder list

Membership resolves again only when a row's lineage fields change, keying
only rows the catalog replaced; labels come from the current rows. A child
Source Control's newer status read is handed to the folder list's summary,
so Back shows what an action did without another read.

* fix(mobile): folder summary takes child reads as they land and ignores server health

Membership depends only on each relayed server's installation, so health
and relay flips no longer resolve the folder again. A child Source
Control hands each status read to the folder summary as it is accepted,
so a summary read answering just after can't hide it, and an older read
never replaces a newer summary failure.

* fix(mobile): folder summary skips restored and cached reads that could undo newer ones

Persisted status is marked restored before anyone hears of it, so a
child screen never hands an earlier launch's status to the folder list.
A cached read caught up on opening writes only an idle summary and never
cancels one in flight. Perf contracts count real lineage serializations,
committed row renders and summary publications.

* fix(mobile): clear the restored mark on any answer but the restore's own

A live answer timed before the stored record, as after a clock
correction, is still this launch's, so its reads and the folder summary
treat it as confirmed.

* fix(mobile): the restore's own write skips clearing its mark only once

A listener replacing restored data as it hears of it writes this
launch's answer, so the mark clears for it too.

* test(mobile): type folder Source Control test fixtures without assertions

* test(mobile): name mocked modules with type-only namespace imports

* feat(mobile): show folder worktrees as cards on the sheet surface

Each attached worktree is its own grouped card on the grey sheet
surface, the look the phone's option sheets use, so rows read apart
from the page.

* fix(mobile): keep folder Source Control's states on the card surface

Loading, empty, error and the list now share the sheet surface, so the
screen no longer changes background between states.
2026-11-08 20:01:22 -08:00
Neil 19043a3d76 refactor(mobile): organize pairing, session, RPC and host owners (#39846)
* refactor(mobile): give relay and encryption concrete owners

* refactor(mobile): organize session and review feature owners

* refactor(mobile): organize RPC and host ownership

* test(mobile): point render fixtures at concrete owners

* refactor(mobile): use explicit type-only owner imports
2026-11-08 07:19:05 -08:00
Kelvin Amoaba 4c43219b74 perf(mobile): open Jump back in and notifications inside the host document (#39474)
* perf(mobile): open Jump back in and notifications inside the host document

* fix(mobile): gate open targets on page 3, keep notification suppression, fold double taps

* fix(mobile): report the shown session from host documents and only open this host's sessions

* test(mobile): ignore the page's location report in the agent-history notify check

* fix(mobile): let a Back before the paint gate settle the host stack

* refactor(mobile): build the route-param clear frame beside its name
2026-11-07 23:39:10 +00:00
Neil bb5f37c916 feat(pairing): unscanned desktop pairing codes expire (QR 10 min, link 60 min) (#37957)
* feat(pairing): unscanned desktop pairing offers expire (QR 10 min, link 60 min)

Headless serve/orcad mint offers without a TTL, so they never expire.
Paired rows and rows without offerExpiresAt are unaffected.

* feat(pairing): refresh the mobile QR before it expires and show runtime link expiry

The QR re-mints a minute before expiry while visible; an unused runtime
link shows its expiry and, once expired, is replaced by a notice. Web
clients rejected while pairing now suggest asking for a new link.

* feat(mobile): say a refused pairing code expired or was replaced

A first pairing the desktop refuses (direct or Relay) now asks for a new
code instead of showing the raw transport error.

* refactor(pairing): replace type assertions in code-refusal detection and tests

* test(mobile): re-record pairing race golden for refused-code error

* fix(pairing): keep pairing codes valid across sleep and stale registry writers

- QR refresh rechecks the wall clock every 15 s and on window focus, so a
  computer waking from sleep never keeps showing an expired code.
- A registry save from a process with an older copy can no longer reset a
  paired row back to unscanned (which would let its offer expire).
- The QR caption says how long a copied code works.

* test(pairing): annotate the IPC handler stub cast
2026-11-06 16:23:44 -08:00
Kelvin Amoaba 8ab385187e feat(mobile): let the host page open a target inside its own document (#39062)
* feat(mobile): let the host page open a target inside its own document

* fix(mobile): skip a duplicate open, re-render the stack only for a waiting route

* fix(mobile): resolve the open target through Expo and open a target that changed before mount

* test(mobile): keep Back in one open-target case

* refactor(mobile): hold routes under the top with one released flag

* refactor(mobile): own the navigator ready listener in the effect

* fix(mobile): leave single-route stacks drawn from the start
2026-11-06 16:55:45 +00:00
Kelvin Amoaba d5afa9f2f9 feat(mobile): add an encrypted on-device store (#38954)
* feat(mobile): add an encrypted on-device store

One AES-256-GCM key in the pairing keychain seals one file per value, bound to its host, table and key. Cache rows are LRU-capped at 128 MiB; drafts are written as tmp, delete, move and refused past 16 MiB. Launch upkeep (orphan hosts, draft TTL, lone tmp recovery, cap totals) runs in idle slices after the splash, and host removal wipes the host's rows. No consumers yet.

* style(mobile): use a ternary for the cache row write

* fix(mobile): keep a lone draft tmp before reuse and settle every row read
2026-11-06 16:51:07 +00:00
Kelvin Amoaba 489a6a66a4 perf(mobile): reopen Source Control's Changes list from memory instead of rescanning (#38988)
* perf(mobile): reopen Source Control's Changes list from memory instead of rescanning

* fix(mobile): keep action errors through background status reads

* fix(mobile): let only explicit status reads clear Source Control's action error

* refactor(mobile): simplify the query layer and the Changes compare trigger

* fix(mobile): follow language switches in Changes' empty states
2026-11-06 16:46:31 +00:00
Kelvin Amoaba b8969c9c53 feat(mobile): split Home into Feed, Usage, Automations and Settings tabs (#38206)
* revert(mobile): drop the details card on session tab taps

Reverts 852391da0f (#36395). The card popped up on every tab switch.
Tapping a tab switches tabs again, and the session title card goes back
to its own owner from #30389. Keeps later changes to these files: tab
press feedback, the compact top bar's + button, and #36866's keyboard
keep-focus for title taps.

* fix(mobile): hide branch and folder when the setting is off

The phone's workspace row always printed the branch or folder path, so the
Branch name / Branch / folder path toggle under Card display did nothing.
The shared card details now carry that rule, and the row reads it.

* fix(mobile): centre the chevron on Home list rows

* fix(mobile): scroll sheets taller than the screen

Content-sized sheets ride the keyboard by translation, but their height cap ignored that lift, so a tall sheet pushed its top off screen with no way to scroll back to it. The cap now gives back the keyboard lift. Sheets that scroll their own list can now shrink to the cap instead of clipping it, and the GitHub Pages picker no longer nests its list inside the drawer's ScrollView.

* feat(mobile): show each desktop's machine kind and model

The desktop now reports whether it is a laptop, desktop or server, and its
model, on status.get. The phone stores it with the other last-known host
fields and turns it into a line like "MacBook Pro · macOS".

* feat(mobile): edit a host from its screen and align the Automations bar

The host screen's menu gains Edit host and Network diagnostics. Edit host moves
onto the standard bar and gains Remove host. Automations uses the standard bar
with its switcher pinned under it, as Source Control does.

* feat(mobile): arrange Home and bring back stats and account usage

Home drops the Jump back in times, names the repo on every Jump back in row
(#37642), shows each desktop's machine kind, and adds stats and account usage
at the bottom. A new Arrange button reorders and hides sections, saved on the
phone.

* fix(mobile): keep the page bundle within budget and show the machine on the host screen

The edit route gets a web stub so its native-only removal flow stays out of
the page's chunks, and Automations keeps its own segment style. The host
screen header shows the machine line like Home does.

* fix(mobile): give the edit route's page stub its own module

A bare re-export of the catch-all route compiled to the same asset as
[...page], so the page manifest listed it twice and the desktop template's
inventory check refused the build.

* feat(mobile): turn Home into Feed, Usage, Automations and Settings tabs

Feed keeps agents (needs-you first, five then Show all), desktops with a
needs-you count, and Tasks; New workspace moves to a floating button.
Usage shows stats and per-desktop account usage, Automations a per-desktop
summary with on/off switches that opens the page for editing (new=1 opens
its editor). Settings becomes a tab. Arrange Home is removed: tabs replace
the long scrolling Home it was for.

* style(mobile): darken the accent blue slightly

* style(mobile): give the Home Tasks row the desktop tile icon

* style(mobile): condense the Home Feed

Smaller tiles, type and gaps; a desktop is two lines with its needs-you
count as an amber pill; the Tasks row drops its duplicate heading.

* style(mobile): drop the Last known prefix on Home desktop rows

* chore(mobile): bump to 0.0.63 and Android versionCode 27

* test(mobile): re-record Linear task recordings for the darker accent blue

* test(mobile): check the page Back stack on Tasks now that Edit host is native

* fix(mobile): pass the Usage tab's limit window to the shared usage helpers

* fix(mobile): type the Usage tab test to the account-slot limits and keep the tab under 400 lines
2026-11-04 20:35:53 +00:00
Kelvin Amoaba 8a4dd3a7bb feat(mobile): improve mobile terminal input (#37900)
* feat(mobile): bring back the terminal key row and one live input

Every terminal tab, shell or agent, gets the dock from before #36166:
the scrolling key row (desktop width, Paste, the built-in keys, custom
keys, add) above one live field that types straight into the terminal,
with the attach and mic buttons beside it. The field keeps today's 3:1
outline and focus ring, and the keys use today's chips and press styles.

The Keys/Message toggle, the Message composer, the arrow pad, the ⋯
sheet on the row and the per-terminal mode preference go. A stored mode
from an older build is never read. Sticky ctrl/alt/shift and the More
keys sheet stay only behind the iPhone Duo rail, which shipped shells
still draw; the page reports no composer, so shipped shells grey their
input-mode key and newer shells hide it.

* refactor(mobile): delete the buffered terminal line

With one live input there is no way to write a terminal line first and
send it, so the per-terminal drafts and their storage, the Send path,
command-field dictation, draft restoration and the terminal setting for
autocomplete and autocorrect (which only applied to that line) go.
Dictation in a terminal always types into it live. Drafts and the setting
saved by older builds are never read.
2026-11-04 06:01:18 +00:00
Neil d09519f0f1 refactor: group workspace and runtime contracts by defining owner (#38018) 2026-11-03 20:19:21 -08:00
Kelvin Amoaba a3efdcb21b feat(mobile): GitHub review threads, viewed sync and line comments on the diff screen (#37073)
* feat(mobile): GitHub threads, viewed sync and line comments on the diff screen

Committed files of a GitHub pull request now show its review threads under
their lines with Reply and Resolve, take their viewed state from GitHub and
sync the checkbox and Viewed · next file back through setPRFileViewed. A tap
or a long-press drag picks lines and opens a sheet that sends the note to
the workspace's agent through the existing send path, or posts it as a
review comment. Threads and GitHub comments appear only while the local
branch is at the PR head, the same contents desktop shows them on;
otherwise the file says to push. openDiffForFile takes an optional line for
a thread's Open in diff.

* test(mobile): use a type import for the line-mutations recording adapter

* fix(mobile): name the staged or unstaged side in the jump sheet's file labels
2026-11-01 18:38:23 +00:00
Kelvin Amoaba 3edc370cdf feat(mobile): diff screen with jump to file, folded context and viewed/stage next (#36998)
The review screen becomes the one diff screen from the approved design.
It walks the Changes section the file came from (uncommitted, staged or on
the branch) or one commit's files, so 'N of M' and next/previous stay in
that list. The title opens a jump-to-file sheet built on the shared
source-control tree, with search and viewed boxes. Unchanged runs fold the
way desktop's diff does. The bar's main button is Stage · next file for
uncommitted files and Viewed · next file otherwise; Discard and Unstage move
to the menu. Filter chips, hunk jumps and Stage Reviewed are gone.

openDiffForFile also takes { kind: 'commit', commitOid, filePath }, read
through git.commitCompare and git.commitDiff.
2026-11-01 18:07:43 +00:00
Kelvin Amoaba 2e1f439620 feat(mobile): open every changed file on the diff screen (#36937)
Source Control rows used to open a file three ways: the review screen, a
desktop editor tab the session then switched to, or a text-only branch
drawer. Every row now calls one openDiffForFile entry point that pushes the
review screen. The drawer, the session tab reveal and their handlers are
gone; Open in Session stays in the review screen's menu.
2026-11-01 17:53:52 +00:00
Kelvin Amoaba 6aa71261b9 feat(mobile): press feedback everywhere, smoother motion, and Reduce Motion for sheets (#36885)
* fix(mobile): stop page bounce and input zoom; URL keyboard for new browser tabs

* feat(mobile): smoother motion, press feedback everywhere, reduced motion for sheets

Working rings and the tool-run pulse run as compositor animations on the
page. Sheets, the right panel, the page stack and the pager cross-fade under
Reduce Motion. The right panel shares the sheet's drag physics. The composer
cross-fades Send/Stop/Save and the mic, jump-to-latest and prompt cards ease
in, banners ease their height, and every Pressable shows a pressed state.
Pairing gets a success beat, and the clean state fades in after a commit.
2026-11-01 04:29:28 +00:00
Kelvin Amoaba 8dde752dc7 feat(mobile): put Settings, Source Control and remaining lists on the shared rows and bar (#36719)
The eight native Settings screens use the shared NavBar and grouped rows,
Source Control's tabs move into the bar's segmented control, and Accounts,
Troubleshoot, the custom key editor, the Tasks pickers and drawers and the
workspace details sheet drop their hand-rolled rows for ListRow.
2026-11-01 03:15:35 +00:00
Kelvin Amoaba 563ada1343 feat(mobile): polish press feedback, sheet motion, states, spacing and layout jumps (#36713)
* feat(mobile): polish press feedback, sheet motion, states, spacing and layout jumps

Every control presses and disables the same way, with one haptic rule.
Sheets follow the finger and settle without bounce, pickers stack instead of
swapping, and screens slide over a dimmed, shifted parent. Loading, empty,
error and offline states share one view with plain-language errors, rows and
labels line up on one grid, and screens stop jumping as data arrives.

* fix(mobile): settle voice, tasks and accounts states; keep host snapshot current

Voice settings with no paired desktop shows the connect state instead of
loading forever. A failed task settings read after a successful probe retries
hydration. The shared host-list snapshot drops on invalidation and ignores
stale passes. Accounts shows a re-pair state on auth failure, and busy
action-sheet rows keep their disabled state for screen readers.
2026-11-01 02:45:03 +00:00
Kelvin Amoaba d618a85ffd feat(mobile): redesign sheets, pickers and list screens (#36585)
Sheets slide on iOS's curve over their own height, ease when their content
changes, and paint a lighter surface with grouped rows and a drawn switch.
Create worktree, the model picker, the GitHub issue sheet, file preview,
Agent Session History and the task list take the redesign draft's layouts
at the app's smaller type sizes.
2026-10-31 04:35:07 +00:00
Brennan Benson ae09815770 Support automations in Orca Mobile (#31617)
* Add host-owned automations flow to mobile

* fix: resolve initial mobile automation CI failures

* Preserve automation target identity and mobile action state

* Preserve selected automation targets through discovery and terminal launch

* Cover draft reversion after uncertain automation creation

* Preserve automation target and submitted action authority

* Preserve selected hosts and editor operations across restored state

* Refresh mobile web bundle measurements for merged routes

* Fix automation history observation and catalog scaling

* Fix automation mobile presentation and merged launch bindings

* Refresh measured mobile bundle sweep and correct automation test inputs

* Move real-module test loads to collection and consolidate imports

* Use typed row access to count worktree ownership reads

* Refresh selected automation history on matching host events

* Fix automation contract types and merged test imports

* Fix automation theme updates and committed history ownership

* Update folder terminal contract fixtures for canonical host catalogs

* Consolidate historical session activation fixture imports

* Repair automation contract project boundaries and owner type ports

* Preserve acquired automation folder owners and fix integration lint

* Retain terminal pane owners captured at connect

* Use checked pane manager context in owner retention test

* fix: adapt merged editor and terminal test contracts

* fix: preserve captured automation targets and terminal owners

* fix: honor explicit automation source clears and refusal contracts

* test: construct terminal transport mocks with checked types

* test: supply retained-owner context in terminal fixtures

* test: align terminal fixtures with callable mocks and store ports

* fix(mobile): localize automation screens and run details

* fix(mobile): use automation translations in context

* fix: preserve editor owner checks and automation repair guidance

* fix: reconcile captured workspace contracts after main sync

* Repair automation integration tests and retained target diagnostics

* Keep test support owned by registered unit roots

* Expose full blocked automation run reasons in menus

* Anchor mobile bundle envelope to measured route sweep

* fix(mobile): localize coded automation run failures

* fix: preserve automation decisions and captured resource ownership

* fix: qualify remaining automation workspace owner consumers

* fix: preserve resolved watch and child editor owners

* fix(editor): share qualified worktree watch ownership

* fix(editor): reuse immutable repo ownership lookup

* fix: preserve host ownership without duplicate catalog scans

* fix: align automation destination host types and ratchets

* fix: align mobile bundle envelope with measured sweep

* fix(mobile): resolve automation setup policy before save

* test(mobile): qualify reconciled automation target inspection

* fix(mobile): keep server setup consent within its authority

* fix: accept narrow qualified workspace owner snapshots

* fix: reuse qualified owner state for workspace directories

* fix(mobile): localize known automation orphan reasons

* Correct automation controller and Chat harness types

* Refresh editor requests after paired host restart

* Refresh measured mobile web bundle envelope
2026-10-30 20:40:04 -07:00
Kelvin Amoaba a079f51991 feat(mobile): unify corner radii across the app (#36437)
* feat(mobile): give every corner one of three shapes

Corners had drifted to 17 different radii, so a screen mixed 6 pt
buttons, 14 pt cards, 12 pt groups and 4 pt badges. Every corner now
comes from the shape of what it is:

- control (12): anything you tap — buttons, icon buttons, fields,
  pickers, segmented controls, key caps.
- surface (16): anything that holds content — cards, groups, sheets,
  banners, code boxes. Dialogs and the composer box use floating (24).
- pill: badges, chips, status pills, dots, avatars and the composer's
  own round buttons.
- tile (10) for icon squares and mark (4) for inline code and check
  squares; nested shapes take the parent's radius minus the gap.

Every rounded style also asks for the continuous (squircle) corner
curve; iOS draws it, Android and the web ignore it.

* fix(mobile): keep circles and pills on the circular corner curve

The continuous curve squares off a corner radius that reaches half the element's size, so the FAB, dots, avatars and the composer's round buttons stopped being round on iOS.

* fix(mobile): put the anchored detail card on the surface radius

* fix(mobile): keep the circular curve on unclipped bordered styles

React Native strokes an unclipped visible border on a circular path while it fills the background with the continuous curve, so the two edges drifted apart at the corners.
2026-10-30 21:27:30 +00:00
Brennan Benson 6a9b1d786f feat(mobile): tap the session title to see its full name, path and host (#30389)
* feat(mobile): tap the session title to see its full name, path and host

A sideways phone caps the title at 160pt beside the tabs, so long worktree names were cut off with no way to read them. Tapping the title now opens a card under the top bar, built like desktop's tab hover card, with the full name, the worktree's path and the host. It fades and slides in over 150ms (fade only with Reduce Motion), and any tap outside closes it.

* fix(mobile): keep the worktree-name reset effect unchanged; type-only View import; lazy card animation value

* fix(mobile): preserve title card bounds and execution host identity

* test(mobile): complete title card platform mocks

* fix(mobile): separate detail card from title trigger

* style(mobile): apply pinned formatter wrapping

* fix(mobile): reopen session details during the closing animation

* style(mobile): wrap the session title imports

* Keep session title activation on one target through card exit

* Host session details above page navigation and retain input scope

* Keep the title target clear as its layout changes

* Clarify title-card types and observer cleanup for checks

* Keep mobile title-card requests and visual exits under one owner

* Make the existing mobile title an explicit web click target

* Keep mobile title details nonmodal through their visual exit

* Follow the active mobile palette in session title details

* Use array syntax for title card motion fixture

* Localize the mobile workspace details hint

* test(mobile): cover title card release to a higher sheet

* Refresh measured mobile web chunk envelope
2026-10-30 13:48:10 -07:00
a803cbead8 feat(mobile): iPhone Duo key rail with D-pad, split terminal panes and half-fold layout (#35177)
Carries over #33221 and #33210. Replaces our #34484 Duo support with the community design, on top of main's rebuilt terminal key bar (#36166).

Fixes #33200

Co-authored-by: Takeshi Matsumoto <zytakeshi520@gmail.com>
Co-authored-by: Lars Keggenhoff <lars@kghf.io>
2026-10-30 16:35:12 +00:00
Kelvin Amoaba 9b4c899dc8 feat(mobile): match every text input to the chat composer and rebuild the terminal dock (#36166)
* 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
2026-10-30 04:51:47 +00:00
Kelvin Amoaba 2e5711fcaa fix(mobile): use paired ports in firewall help (#36130)
* fix(mobile): use paired ports in firewall help

* fix(mobile): use a namespace type in diagnostics test
2026-10-29 22:55:38 +00:00
Kelvin Amoaba 41cd866fb1 fix(mobile): recover from native screen render errors (#36121)
* fix(mobile): recover from native screen render errors

* fix(mobile): avoid replaying launch links after recovery

* fix(mobile): discard launch intent before recovery Home

* test(mobile): correct recovery fixture types
2026-10-29 22:44:22 +00:00
Kelvin Amoaba a51164379e fix(mobile): explain scanned download QR codes (#36128) 2026-10-29 22:36:27 +00:00
OrcaWinandOrcaWin a99bc36593 feat(mobile): localize tasks, new workspaces and source control (#35646)
* feat(mobile): localize tasks, new workspaces and source control

Moves the last ~670 strings (task lists and boards, issue and PR sources, the
new-workspace flow, and source control) to the translation API, with all ten
translations. What remains in the coverage baseline is reviewed non-copy: key
names, schema errors and log lines.

- Source control section titles recompute on a language change

* fix(mobile): align catalog terminology across screens

A whole-catalog pass per language reconciled terms that differed between batches
(host/desktop, dictation, transcripts, address form) with the glossaries and the
desktop catalogs. The page bundle verifier now reports catalog bytes separately.

* fix(mobile): keep fetched history and source error slugs language-independent

History rows are derived from the fetched page at render so relative times follow a
language switch; quality-gate follow-ups for the tasks and source control migration.

* fix(mobile): name Android notification channels in the UI language

* chore(mobile): drop catalog entries for removed source-control copy

* fix(mobile): re-localize the composer source hook on current main

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 21:11:04 -07:00
OrcaWinandOrcaWin 5d235b624d fix(mobile): preserve text size selected during hydration (#34846)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 20:35:30 -07:00
OrcaWinandOrcaWin ccd0829e6f feat(mobile): localize app screens, settings, pairing and host lists (#35498)
Moves ~600 strings in the root screens, settings, pairing, onboarding, accounts,
agent history, diagnostics, connection status, home and host workspace lists to the
translation API, with all ten translations.

- Connection verdicts carry an explicit `dialing` flag instead of matching the
  "…" ending of an English label
- Update-failure copy and connection-path accessibility labels are built from data,
  not by editing translated text
- Workspace status names stay the host's labels, as on desktop; transport errors
  stay English
- The stale-key check keeps a plural family while any of its forms is referenced

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 18:03:37 -07:00
OrcaWinandOrcaWin 12a7d4c13a feat(mobile): localization infrastructure and language setting (#35399)
* feat(mobile): add UI localization infrastructure

Mobile follows the phone's language (or an in-app choice under Settings > Appearance)
across the same 11 languages as desktop, switching live like the theme does.

- i18next with desktop's translate(key, fallback, options) call shape; catalogs in
  mobile/src/i18n/locales load lazily, English fallbacks stay inline
- Hermes lacks Intl.PluralRules: load the FormatJS polyfill with the 11 languages' rules
- OTA pages get the shell's language through an optional bridge init field
- iOS permission prompts localized; iOS and Android 13+ per-app language pickers
- verify:mobile-localization and a coverage ratchet run in lint, check:changed and CI

* fix(mobile): mount pages after the newest language request; tighten localization gates

- Wait for the latest page language activation, not a superseded one
- Keep literal fallbacks when a key also has a dynamic one
- Count headerTitle as visible copy; select the mobile check when the runtime catalog generator changes

* feat(mobile): repaint themed components on language changes

Components that read the theme already subscribe for repaint; a language switch
repaints them too, so labels built by helpers during render follow it. RPC
recordings load the real i18next and JSON catalogs.

* fix(mobile): scope the translate() gate to render bodies and memos; prune stale keys on sync

Handlers and effects may call translate() when they run. sync:mobile-localization now
removes keys no code references from every catalog.

* fix(mobile): use node: imports in the locale config plugin; pass uiLocale in bridge hook test

* chore(mobile): refresh the localization coverage baseline

* fix(mobile): follow render callbacks in the translate() gate; keep used plural siblings on prune

Also let anonymous default-exported screens count as components, flag any plural
family a locale started, and mark JSON modules as ES modules in the recording loader.

* fix(mobile): treat async and named local callbacks as handlers in the translate() gate

* chore(mobile): refresh the localization coverage baseline

* chore(mobile): refresh the localization coverage baseline

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 17:14:05 -07:00
NeilandKelvin Amoaba 737ba1595b fix(mobile): keep voice settings in the order you change them (#31691)
* fix(mobile): drop voice settings replies older than the latest change

An older save that replies last could put the previous setting back on screen. Ignore mutation replies and errors that a newer change has superseded.

* fix(mobile): keep the Voice screen on the connected desktop

Key the screen by host so a late reply from a desktop the phone switched away from cannot land on the newly connected desktop's settings.

* fix(mobile): re-read Voice settings when an older save succeeds late

The host finishes a model delete only after removing its files, so a newer change can reply first with the model still selected. Dropping the older reply left the deleted model shown as in use; re-read instead.

* fix(mobile): keep Voice model errors and the screen through reconnects

A newer setting change does not replace a failed model select, download or delete, so show those errors again. Key the screen on the last connected desktop so a reconnect of the same desktop no longer remounts it.

* test(mobile): pin Voice model-delete errors after a newer change

* fix(mobile): re-read Voice settings after any failed save

* fix(mobile): re-read Voice settings only after every pending change settles

A read sent while a model delete is still running can return the deleted model after the delete's own reply. Skip reads while a change is pending, and re-read once when all settle if any reply was skipped.

* fix(mobile): keep a failed Voice model action's error on screen

A lone failed select or delete changed nothing on the phone, so it no longer starts a re-read that clears its error. A failed switch still re-reads to undo its optimistic flip.

* fix(mobile): let Voice reads clear only their own load errors

A re-read after a failed or superseded change cleared the change's error before the user could read it. Keep load and change errors apart; re-read after any failure again, which also undoes a failed switch flip.

---------

Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-10-28 23:06:53 +00:00
NeilandKelvin Amoaba e0b5a42852 fix(mobile): handle invalid pairing links and start fresh for each invite (#31705)
* fix(mobile): validate pairing routes and isolate invite lifetimes

Repeated code parameters crash parsing, and replacing an invite retains old attempts and callbacks. Validate route input and key confirmation state by invite; allow confirmation content to scroll on short screens.

* fix(mobile): retire pairing immediately when Back is pressed

* fix(mobile): keep the pair confirmation layout unchanged

The ScrollView wrapped ConnectionLog's own vertical scroller without nested
scrolling on Android and was not needed for the invite-lifetime fix. The
repeated-code case is covered by the route-state test.

---------

Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-10-28 17:57:24 +00:00
OrcaWinandOrcaWin 00666138a7 fix(mobile): show pairing progress and errors without camera access (#34739)
* fix(mobile): show pasted pairing feedback without camera access

* test(mobile): drop unreachable revoke and mock-only listener tests

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 23:06:25 -07:00
Kelvin Amoaba 941f4ece37 feat(mobile): support the iPhone Duo folded and unfolded, with controls in its side status bar (#34484) 2026-10-27 22:16:33 +00:00
Kelvin Amoabaandzhangxaochen 2a9d874e67 fix(mobile): leave Agent Session History when you resume a session from it (#34485)
* fix(mobile): leave Agent Session History when resuming a session from it

Resuming always pushed the session screen, so Back from it landed on the
history screen again (A -> B -> A). History now learns it was opened from a
session (origin=session, as Source Control does): resuming into that same
workspace pops back to it, anything else replaces the history screen.

The history screen is a page in the shell, and the page could only ask the
shell to push. The navigate notify gains an optional replace flag; a page with
no in-page history asks the shell to replace its screen, and one with history
below pops its own entry and has the shell push. Older shells strip the flag
and push as before.

Co-authored-by: zhangxaochen <3416677+zhangxaochen@users.noreply.github.com>

* fix(mobile): show the resumed terminal on the session that opened Agent Session History

Going back to the session screen below kept its old tab: the session pins its
own pick over the host's caller-scoped snapshot. History now hands the resumed
terminal to that session through the registry Source Control already uses for
opened diffs, renamed to session-screen-handlers since it carries both.

* refactor(mobile): positional replace flag on notifyNavigate, share the owned-session test fixture

* fix(mobile): keep MobileWebShellScreen under its line cap

---------

Co-authored-by: zhangxaochen <3416677+zhangxaochen@users.noreply.github.com>
2026-10-27 17:58:49 +00:00
Kelvin Amoaba f87a746200 feat(mobile): light and dark themes with desktop's palettes (#34217)
* 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.
2026-10-27 17:35:31 +00:00
Kelvin Amoaba d7a8bb9240 fix(mobile): show the diff when tapping a changed file from a session (#34073) 2026-10-26 22:42:11 +00:00
OrcaWinandOrcaWin 7d6603aa17 [comment audit] Complete repository-wide comment cleanup (#33249)
* [comment audit] Align legacy failure-read counts with cached display

* [comment audit] Condense shared provider lifecycle and browser recovery comments [skip ci]

* [comment audit] Condense shared generation, path and preview comments [skip ci]

* [comment audit] Condense host, file and Git contract rationale [skip ci]

* [comment audit] Tighten Git lifecycle and provider contract comments [skip ci]

* [comment audit] Clarify shared host authority and launch isolation [skip ci]

* [comment audit] simplify local access mobile and native chat contracts [skip ci]

* [comment audit] simplify native chat presentation and state contracts [skip ci]

* [comment audit] simplify native runtime and provider contracts [skip ci]

* [comment audit] simplify migration and orchestration contracts [skip ci]

* [comment audit] simplify plugin trust and process capture rationale [skip ci]

* [comment audit] simplify terminal delivery and remote compatibility rationale [skip ci]

* [comment audit] clarify remote recovery and launch wire rationale [skip ci]

* [comment audit] shorten shared RPC compatibility and runtime evidence comments [skip ci]

* [comment audit] simplify secure storage shell startup and sidebar rationale [skip ci]

* [comment audit] clarify sidebar, skill and SSH invariants [skip ci]

* [comment audit] condense structured chat delivery and timing rationale [skip ci]

* [comment audit] condense terminal replay and telemetry invariants [skip ci]

* [comment audit] clarify launch permission and terminal delivery rationale [skip ci]

* [comment audit] clarify workspace ownership and layout contracts [skip ci]

* [comment audit] wait for fitted and painted SSH terminal links

* [comment audit] clarify layout persistence and session ownership [skip ci]

* [comment audit] clarify host routing and workspace lifecycle contracts [skip ci]

* [comment audit] clarify startup persistence and app lifetime comments [skip ci]

* [comment audit] clarify recovery and activity boundaries [skip ci]

* [comment audit] condense activity and artifact invariants [skip ci]

* [comment audit] condense automation authority contracts [skip ci]

* [comment audit] simplify automation scheduling and history contracts [skip ci]

* [comment audit] clarify browser chrome and annotation lifecycles [skip ci]

* [comment audit] clarify browser routing and retained guest ownership [skip ci]

* [comment audit] clarify browser recovery and document ownership comments [skip ci]

* [comment audit] restore hosted runners required by native IME fixtures

* [comment audit] shorten preview, palette and dashboard invariants [skip ci]

* [comment audit] clarify terminal preview, dashboard and retention comments [skip ci]

* [comment audit] clarify diff-note recovery and editor lifecycle comments [skip ci]

* [comment audit] shorten rich-text and combined-diff ownership comments [skip ci]

* [comment audit] shorten autosave, draft recovery and model ownership comments [skip ci]

* [comment audit] shorten save-queue, notebook and Markdown constraints [skip ci]

* [comment audit] shorten Monaco, PDF and rich Markdown safeguards [skip ci]

* [comment audit] clarify rich Markdown source and selection safeguards [skip ci]

* [comment audit] clarify editor loading and emulator stream lifetimes [skip ci]

* [comment audit] trim emulator and feature tour narration [skip ci]

* [comment audit] clarify floating workspace and GitHub cache ownership [skip ci]

* [comment audit] trim provider controls and Linear filter explanations [skip ci]

* [comment audit] clarify pairing and chat resume lifetimes [skip ci]

* [comment audit] clarify chat delivery and transcript lifetimes [skip ci]

* [comment audit] clarify session options and host-owned status [skip ci]

* [comment audit] clarify draft durability and live-status precedence [skip ci]

* [comment audit] Trim chat send and model ownership explanations [skip ci]

* [comment audit] Shorten transcript ownership and send recovery comments [skip ci]

* [comment audit] Simplify native chat composer and transcript hook comments [skip ci]

* [comment audit] Shorten native chat scroll and structured session explanations [skip ci]

* [comment audit] Trim workspace picker and onboarding commentary [skip ci]

* [comment audit] Simplify pet rendering, review cache and quick open comments [skip ci]

* [comment audit] Trim sidebar and session history explanations [skip ci]

* [comment audit] Condense session resume and review checks comments [skip ci]

* [comment audit] Shorten checks state and file explorer refresh comments [skip ci]

* [comment audit] Trim plugin bridge and source-control action rationale [skip ci]

* [comment audit] Trim source-control listing and review rationale [skip ci]

* [comment audit] Shorten sidebar lifecycle and explorer safeguards [skip ci]

* [comment audit] Condense Settings account and appearance rationale [skip ci]

* [comment audit] Trim pairing and repository Settings explanations [skip ci]

* [comment audit] Condense Settings search SSH and terminal safeguards [skip ci]

* [comment audit] Shorten Settings voice and provider ownership comments [skip ci]

* [comment audit] Condense Settings draft persistence and host-state rationale [skip ci]

* [comment audit] Trim Settings hooks and sidebar setup rationale [skip ci]

* [comment audit] Condense sidebar deletion and board-filter safeguards [skip ci]

* [comment audit] Condense worktree cards, host ownership and Markdown contracts [skip ci]

* [comment audit] Condense sidebar drag, folder and filtering contracts [skip ci]

* [comment audit] Condense sidebar parity, sleep and host ownership contracts [skip ci]

* [comment audit] Prune focus-read baseline after comment cleanup

* [comment audit] Clarify sidebar visibility, board drops and agent evidence [skip ci]

* [comment audit] Tighten sidebar listing, drag and reveal contracts [skip ci]

* [comment audit] Clarify viewport geometry and skill update safeguards [skip ci]

* [comment audit] Tighten skill inventory, usage and host status comments [skip ci]

* [comment audit] Clarify usage ownership and resource kill safeguards [skip ci]

* [comment audit] Tighten tab selection, rename and search contracts [skip ci]

* [comment audit] Tighten tab-strip geometry and drag ownership comments [skip ci]

* [comment audit] Tighten Tasks recovery, pagination and mutation comments [skip ci]

* [comment audit] Tighten provider loading and terminal recovery comments [skip ci]

* [comment audit] Tighten completion, cadence and PTY ownership comments [skip ci]

* [comment audit] Clarify terminal restore and parked-pane boundaries [skip ci]

* [comment audit] Tighten PTY startup and replay explanations [skip ci]

* [comment audit] Clarify PTY identity and delivery ownership [skip ci]

* [comment audit] Shorten remote reconnect and input replay rationale [skip ci]

* [comment audit] Condense terminal parking clipboard and file link comments [skip ci]

* [comment audit] Clarify IME ownership and trim trace history [skip ci]

* [comment audit] Shorten pane recovery and parked watcher explanations [skip ci]

* [comment audit] Condense snapshot replay and visibility recovery rationale [skip ci]

* [comment audit] Shorten terminal parking and keyboard ownership rationale [skip ci]

* [comment audit] Trim renderer lifecycle and menu rationale [skip ci]

* [comment audit] Condense workspace cleanup ownership and settlement notes [skip ci]

* [comment audit] Clarify renderer hook evidence and source ownership [skip ci]

* [comment audit] Tighten IPC ownership and reconnect explanations [skip ci]

* [comment audit] Trim renderer focus, paste and attention comments [skip ci]

* [comment audit] Shorten scroll, locale and agent lifecycle comments [skip ci]

* [comment audit] Trim agent launch, resume and ownership commentary [skip ci]

* [comment audit] Shorten account, browser and editor comments [skip ci]

* [comment audit] Clarify host-mirror waits, previews and input ownership [skip ci]

* [comment audit] Condense launch recovery and editor tokenization comments [skip ci]

* [comment audit] Condense workspace selection and terminal pane rationale [skip ci]

* [comment audit] Condense terminal fitting and rendering recovery comments [skip ci]

* [comment audit] Condense terminal input and host routing explanations [skip ci]

* [comment audit] Condense ownership and sleeping-session recovery rationale [skip ci]

* [comment audit] Condense structured launch and terminal link explanations [skip ci]

* [comment audit] Condense terminal ownership and workspace file routing rationale [skip ci]

* [comment audit] Condense session persistence and workspace activation rationale [skip ci]

* [comment audit] Condense workspace routing and browser ownership rationale [skip ci]

* [comment audit] Condense mirror recovery and layout authority rationale [skip ci]

* [comment audit] Condense runtime transport and file safety rationale [skip ci]

* [comment audit] Condense runtime graph and structured session rationale [skip ci]

* [comment audit] Condense browser creation and remote tab recovery rationale [skip ci]

* [comment audit] Condense snapshot authority and publisher recovery rationale [skip ci]

* [comment audit] Condense frame, startup and provider cache rationale [skip ci]

* [comment audit] Condense host twin and agent lifecycle rationale [skip ci]

* [comment audit] Condense browser authority and editor cleanup rationale [skip ci]

* [comment audit] Condense editor buffer identity and review cache rationale [skip ci]

* [comment audit] Condense provider lifetime and repository ownership rationale [skip ci]

* [comment audit] Condense reconnect, hydration and terminal retirement rationale [skip ci]

* [comment audit] Condense recovery, reconciliation and persistence rationale [skip ci]

* [comment audit] Condense cleanup ownership and listing admission rationale [skip ci]

* [comment audit] Condense teardown ordering and terminal ownership rationale [skip ci]

* [comment audit] Condense recovery ledger and web host-boundary rationale [skip ci]

* [comment audit] Condense web reconnect and credential lifecycle rationale [skip ci]

* [comment audit] Condense cloud rollout and assignment safety rationale [skip ci]

* [comment audit] Condense relay session and database recovery rationale [skip ci]

* [comment audit] Condense relay placement and protocol compatibility rationale [skip ci]

* [comment audit] Condense build and packaging constraints [skip ci]

* [comment audit] Condense CI gates and validation isolation rationale [skip ci]

* [comment audit] Condense catalog identity and browser validation rationale [skip ci]

* [comment audit] Condense mobile browser and frame-budget rationale [skip ci]

* [comment audit] Shorten mobile route and browser test explanations [skip ci]

* [comment audit] Condense editor and session seam test rationale [skip ci]

* [comment audit] Trim session and terminal closure history [skip ci]

* [comment audit] Shorten terminal browser and census explanations [skip ci]

* [comment audit] Preserve root-only E2E diagnostic baseline

* [comment audit] Condense mobile seam and HTML preview test rationale [skip ci]

* [comment audit] Condense preview instrumentation and render harness rationale [skip ci]

* [comment audit] Condense bundle contracts and native-build constraints [skip ci]

* [comment audit] Shorten native packaging and CI routing rationale [skip ci]

* [comment audit] Condense release tooling and benchmark constraints [skip ci]

* [comment audit] Condense packaging and platform gate rationale [skip ci]

* [comment audit] Shorten mobile route and history rationale [skip ci]

* [comment audit] Condense mobile browser and component rationale [skip ci]

* [comment audit] Shorten drawer and workspace-form rationale [skip ci]

* [comment audit] Trim mobile review and editor-document explanations [skip ci]

* [comment audit] Condense editor lifecycle and Markdown explanations [skip ci]

* [comment audit] Trim mobile file, diagnostics and dictation commentary [skip ci]

* [comment audit] Simplify mobile host-list and workspace-view explanations [skip ci]

* [comment audit] Clarify mobile shell lifetime and bridge delivery constraints [skip ci]

* [comment audit] Condense bridge stream, native request and audio rationale [skip ci]

* [comment audit] Reduce bridge schema and page-client commentary [skip ci]

* [comment audit] Tighten mobile page bridge contracts [skip ci]

* [comment audit] Clarify mobile cache and session constraints [skip ci]

* [comment audit] Condense mobile route and lifecycle rationale [skip ci]

* [comment audit] Tighten mobile shell hook timing rationale [skip ci]

* [comment audit] Clarify route handoff and notification compatibility [skip ci]

* [comment audit] Clarify push registration and dictation cleanup constraints [skip ci]

* [comment audit] Condense keyboard geometry and native media ownership rationale [skip ci]

* [comment audit] Tighten mobile chat scroll and composer concurrency rationale [skip ci]

* [comment audit] Condense mobile reply compatibility and upload ownership rationale [skip ci]

* [comment audit] Condense optimistic echo and scroll ownership rationale [skip ci]

* [comment audit] Tighten stream replay and queued session ownership rationale [skip ci]

* [comment audit] Condense mobile composer and reply-schema constraints [skip ci]

* [comment audit] Clarify mobile transcript recovery and session ownership [skip ci]

* [comment audit] Clarify mobile queue and source-control compatibility [skip ci]

* [comment audit] Condense storage and task launch constraints [skip ci]

* [comment audit] Clarify task schemas and terminal document ownership [skip ci]

* [comment audit] Tighten terminal input and viewport rationale [skip ci]

* [comment audit] Shorten terminal and RPC recorder contracts [skip ci]

* [comment audit] Condense recorder engine and connection contracts [skip ci]

* [comment audit] Shorten host credential and relay recovery comments [skip ci]

* [comment audit] Tighten pairing recovery and bundle transport rationale [skip ci]

* [comment audit] Clarify RPC delivery and workspace catalog boundaries [skip ci]

* [comment audit] Condense catalog and relay entry contracts [skip ci]

* [comment audit] Shorten shutdown and SSH relay delivery contracts [skip ci]

* [comment audit] Condense WSL relay and E2E regression rationale [skip ci]

* [comment audit] Shorten cross-version harness and renderer fixture explanations [skip ci]

* [comment audit] Condense paired-host and E2E lifecycle rationale [skip ci]

* [comment audit] Shorten layout oracle and regression explanations [skip ci]

* [comment audit] Condense paired recovery and ownership regression contracts [skip ci]

* [comment audit] Shorten restart, sidebar and SSH lifecycle contracts [skip ci]

* [comment audit] Condense terminal rendering and IME regression rationale [skip ci]

* [comment audit] Shorten terminal recovery and benchmark contracts [skip ci]

* [comment audit] Condense tooling and Windows lifecycle proof rationale [skip ci]

* [comment audit] Condense workflow routing and release rationale [skip ci]

* [comment audit] Condense mobile security and installer contracts [skip ci]

* [comment audit] Shorten native rationale and stylesheet workarounds [skip ci]

* [comment audit] Shorten Windows visibility probe rationale [skip ci]

* [comment audit] Condense embedded release and signing rationale [skip ci]

* [comment audit] Retain current main test behavior in final reconciliation [skip ci]

* [comment audit] Complete final comment review across current source inventory

* [comment audit] Handle consolidated audit reports before final CI

* [comment audit] Preserve credential storage census detail [skip ci]

* [comment audit] Scale broad changed E2E selections with verified timing shards

* [comment audit] Align E2E assertions with browser close and settled session metadata

* [comment audit] Match existing E2Es to current resource and windowing contracts

* [comment audit] Observe the shared server outage notice in reconnect coverage

* [comment audit] Make existing renderer probes measure settled tab and PTY work

* [comment audit] Align palette E2E selector with task search

* [comment audit] Refresh remaining palette search selectors

* [comment audit] Keep selector correction within selected audit specs

* [comment audit] Await emoji fixture settings inside renderer evaluation

* [comment audit] Cancel fixture fit retries between terminal tests

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-25 04:05:46 -07:00
ea42a203a0 fix(mobile): distinguish delayed dial deadlines from unreachable hosts
Classify substantially delayed connect/handshake deadlines as interrupted
instead of blaming endpoint reachability, retaining the existing close/retry
path and ordinary timeout errors. Limit sleep-clock compensation to observed
background segments and let fresh failures replace delayed evidence.

Remove the stale host-version fallback and discard captured versions when
report hydration crosses an observed reconnect. Independently reviewed;
128 focused tests, adjacent transport contracts and changed quality pass.

Adapted from community PR #24425.
Fixes #18829.

Co-authored-by: Wooseong Kim <innocarpe@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-21 18:49:14 -07:00
Jinwoo Hong f47f632bd7 feat(mobile): Home's New Workspace opens the desktop's create drawer over Home (native part ships with the next app build) (#31305)
* fix(mobile): the home screen's New Workspace opens the create sheet again

The native host-list route dropped the home screen's action=newWorktree when it built
the page's route, so the page opened as a plain list. The route now forwards it, and
the page names it back once applied so a reload does not reopen the sheet.

Reaches phones only with the next native build.

* test(mobile): drop the New Workspace tests that only re-check types and a null guard

* fix(mobile): Home's New Workspace opens the create sheet over Home

Replaces the action=newWorktree route hand-off. The quick action picks a
host (as Tasks does), then mounts the host's create sheet on Home; a
create opens the new workspace's session marked as just created.

The sheet controller becomes a plain visible/onClose component, and the
host screen's route-action state, the action route param and its builder
are deleted.

* fix(mobile): Home's create sheet seeds only proven worktree rows

Home's cold-start seed is a pathless resume row that the name suggester
cannot read, so the sheet now seeds from proven rows and is keyed by host.
The host screen gets one setter for the sheet's visibility and its ref.

* test(mobile): name the Home new-workspace test after the screen it renders

* proto(mobile): Home's New Workspace opens a native drawer hosting the page's create form

Home pushes /new-workspace/<host>, a react-native-screens formSheet over Home whose content is
MobileWebShellScreen for the page route /h/<host>/new-workspace. The page renders the shared
Create Workspace form with its drawers inline, so the form and its pickers fill the native
drawer. The shell's loading, download and failure states render inside the drawer. Prototype only.

* proto(mobile): the New Workspace drawer is the host screen's own sheet over a transparent modal

The native route is a transparentModal hosting the shell over Home; the page route renders the
host screen's NewWorktreeModal on a transparent page, so the drawer is the same component. While
the page loads, the shell shows a placeholder of that sheet (scrim, grabber, spinner or download
bar), and the page's sheet opens in place without its slide. A host that cannot serve the page
(old desktop, blocked, failed) opens the host list instead of a wall in a drawer.

* feat(mobile): Home's New Workspace opens the page's create drawer over a dimmed Home

A transparent native overlay route hosts the host picker and then the page's
/h/[hostId]/new-workspace route, which renders the same NewWorktreeModal as the
host screen's +. The native scrim matches the drawer backdrop and the page's
first drawer opens already dimmed, so Home stays dimmed throughout. Old desktops
without the route fall back to the host list.

* fix(mobile): one loading layer for Home's New Workspace overlay

The overlay route owns a single tappable loading layer (spinner, or the
download on a small card) that stays mounted from the pick until the page
paints, so the fade and spinner no longer restart per shell state. The shell
reports its load and shows the host list for anything it cannot open; the
picker hands the pick over at once and keeps sliding away. The page's first
drawer takes the dimmed backdrop once, and a gate's overlay pending view no
longer stacks a second scrim over a mounted stack. Native /h/[hostId]/new-workspace
redirects to the overlay. Drops the unused session-route params, the
clipboard grant, and pass-through tests.

* feat(mobile): New Workspace loads in a short drawer over an undimmed Home

While the page loads, the overlay shows one short native drawer in the shared
drawer chrome with a spinner or the download, and nothing dims Home: a tap
above it, a drag down or Back cancels. The page's real drawer then slides up
with its own backdrop exactly as on the host screen's +. Drops the native
scrim, the loading card and the already-dimmed backdrop handoff; the overlay's
WebView stays invisible until the page paints, since a fresh one draws opaque.

* feat(mobile): the New Workspace loading drawer dims Home like any drawer

The short loading drawer opens with the shared drawer backdrop and show
duration, and a tap on that backdrop, a drag down or Back cancels. It stays
in the screen's own window (a native Modal over the loading WebView stalls
the page) and goes in the frame the page paints: the shell reports its load
from a layout effect so the WebView shows and the drawer leaves together.

* fix(mobile): the page's first paint waits for a drawer opening with it

A drawer opening as its page screen mounts holds that screen's first-paint
report until its open animation ends, through a hold on the existing report
rather than a new bridge message. The New Workspace overlay's loading drawer
now stays until the create drawer is up, so a cold open no longer shows Home
undimmed between the two.

* refactor(mobile): the New Workspace overlay owns its exits; the loading drawer fades out

The shell no longer imports the feature: an overlay is a shell with
onOverlayLoad, which reports `unavailable` for what it cannot show, and the
overlay route opens the host list for every exit. HostProtocolGate takes one
transparentWhilePending flag. The loading drawer's drag handler follows a
stable cancel, and on paint the drawer fades out eased in, as the shell's page
cover does, because the WebView takes a frame or two to show the page after it
is revealed; removing it outright left Home undimmed for those frames.

* Revert "fix(mobile): the page's first paint waits for a drawer opening with it"

This reverts commit be0913b9d5.

* fix(mobile): Home's host picker leaves when there is no desktop to pick

An unreadable host catalog, or offered desktops that are all gone, left the
picker invisible inside the transparent overlay, holding a screen over Home
with nothing to dismiss it. The catalog read now resolves to no hosts on
failure, and an empty pick list goes back to Home.

* fix(mobile): Home's create drawer names SSH hosts as the host screen does

The page drawer opened from Home passed no host labels, so a project on an SSH
host showed its run target by raw host id. Reading the SSH target summaries
and display overrides moves into one function that both the host screen's
metadata fetch and the page drawer call.
2026-10-21 20:02:11 -04:00
Neil 41fb3c7a9c fix(mobile): retire host edit navigation after leaving the route (#31692)
Saving an endpoint after the user leaves can pop a second screen. Retire navigation ownership while allowing the endpoint save and client refresh to finish.
2026-10-21 16:41:13 -07:00
NeilandChun Chet Ng f6fc6d00f5 fix(mobile): use port 443 for explicit WSS host edits (#31659)
Use port 443 when an explicit WSS host edit omits a port; preserve saved host endpoints, bare-host inheritance and explicit ports.

Adapted from https://github.com/stablyai/orca/pull/31499.

Co-authored-by: Chun Chet Ng <ngchunchet95@gmail.com>
2026-10-21 16:32:07 -07:00
Neilandgsxdsm 47bb876bb1 docs(mobile): clarify buffered terminal autocomplete scope (#31347)
Co-authored-by: gsxdsm <gsxdsm@users.noreply.github.com>
2026-10-21 12:24:29 -07:00
Kelvin Amoaba 8f8c0abfc7 fix(mobile): show the saved restore delay in Terminal settings (#31361) 2026-10-21 18:24:12 +00:00
Kelvin Amoaba b0a7d2eb48 fix(mobile): keep typed commit messages, restore failed shortcut removals, name icon buttons (#30142) 2026-10-18 20:05:28 +00:00
Neil aa07d5891a fix(mobile): break the transport and terminal-document import cycles, and gate cycles after mobile's install (#30290)
* fix(mobile): break the transport and terminal-document import cycles and gate them after mobile's install

client-context re-exported the host-client hooks, which import client-context back: the re-export
barrel is gone and importers (and their test mocks) name host-client-hooks directly. In the terminal
document, the cell-metric getters move to a leaf cell-metrics module and select-mode entry/exit to
selection-mode, so fit, transform, overlay and range no longer import each other. pr.yml lints imports
before mobile's install, when mobile's tsconfig can't load, so Mobile verify now runs the same import
rules over mobile after its install with zero warnings allowed.

* fix(mobile): the browser-pane render harness imports useHostClient from host-client-hooks

Its route source is a template string, so no typecheck saw the removed client-context re-export; the mobile web bundle check did.

* fix(ci): the e2e typecheck ratchet counts the same with or without mobile's install

Specs reach mobile/src/transport, whose expo-crypto and async-storage imports resolve only after mobile's install and then load React Native's globals (numeric timers, a required NODE_ENV), adding errors in unrelated specs. An empty stub pins both, so the static job reads 232 either way.
2026-10-18 04:00:24 -07:00