Commit Graph
87 Commits
Author SHA1 Message Date
Kelvin Amoaba c1f3309c1e fix(mobile): convert Android HEIC photos to JPEG when picked for chat (#41626)
At quality 1 the Android picker hands back raw HEIC, which the chat page's
WebView can't decode, so the attach failed.
2026-11-12 18:56:41 +00:00
Kelvin Amoaba 20a75e4b44 fix(mobile): shrink chat photos to 2000 px before upload (#41514)
Phone photos went up at full size, and agents refuse images over 5 MiB of base64.

Fixes #40844
2026-11-12 11:22:06 +00:00
OrcaWinandOrcaWin 4214d3da1c test: remove low-value input, media, and browser examples (#41484)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-12 01:52:38 -08:00
OrcaWinandOrcaWin 333febd77b test: remove narrow mobile, provider, and utility suites (#41342)
* test: remove low-value mobile classification and wiring cases

* test: remove narrow provider identity and utility suites

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 19:22:20 -08:00
Kelvin Amoaba 1d3bf2d6a9 fix(mobile): send chat with Cmd+Enter in desktop Mac browsers (#41330) 2026-11-12 02:41:44 +00: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
OrcaWinandOrcaWin d5f6fe17bf test: remove 129 low-value cases and 21 whole suites (#41210)
* test: remove 83 low-value cases and ten whole suites

* test: remove 46 more low-value cases and eleven suites

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 11:03:08 -08:00
Kelvin Amoaba dfa6430d99 fix(mobile): keep the Android composer focused when the keyboard switches to a voice IME (#41209)
A keyboard's mic button switches to a separate voice IME, which closes the keyboard and opens the voice panel about 250 ms later. The page read every Android keyboard close as Back and blurred the field at once, so the voice IME's text had nowhere to go. Blur only once the keyboard stays closed for a second; a reopen within that window keeps focus.
2026-11-11 18:22:50 +00:00
OrcaWinandOrcaWin 77ab05bfb1 test: remove 192 low-value mobile tests (#41196)
* test: remove thin mobile forwarding and inventory checks

* test: remove 60 more low-value mobile checks

* test: remove 120 low-value mobile task and document checks

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 09:49:53 -08:00
Kelvin Amoaba a5dbd1cb2f feat(mobile): read dictation progress to VoiceOver and TalkBack (#40504)
* feat(mobile): announce dictation to VoiceOver through the shell

* feat(mobile): speak dictation from the host, so leaving the session and the pill's toasts are announced too

* fix(mobile): say dictation outcomes where they are known, and re-read a repeated live message

* fix(mobile): leave a setup refusal to its setup sheet instead of reading the raw code

* fix(mobile): say cancelled when a kept recording is discarded
2026-11-09 22:52:59 +00:00
Kelvin Amoaba 58733086c9 feat(speech): spell dictated code terms with a personal and per-repo dictionary (#40450)
* feat(speech): spell dictionary terms in dictation, with repo terms and Whisper prompt

* test(speech): pin host repo terms for phone dictation

* fix(speech): keep symbol terms whole, accept null setup params, resolve SSH repos

* refactor(speech): key transcript words once and type phone terms at the reply schema

* refactor(speech): merge speech-types imports in the speech IPC
2026-11-09 19:22:46 +00:00
OrcaWinandOrcaWin c38a8e4b9a test: remove low-value wrappers, inventories, and timing checks (#40284)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 02:52:36 -08:00
OrcaWinandOrcaWin 40abff3220 test: reconcile VM mobile and native test removals with current main (#40154)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 01:02:00 -08:00
Kelvin Amoaba b2fbbbca42 feat(mobile): cancel dictation in place and show which device is transcribing (#40185)
* feat(mobile): cancel dictation in place and show which device is transcribing

* fix(mobile): give each composer its own dictation cancel target

* fix(mobile): keep the dictating composer row on one line

* refactor(mobile): share the dictation mic face and measure the cancel target per platform
2026-11-09 08:36:02 +00:00
Kelvin Amoaba 46451538e4 feat(mobile): remove filler words from text the phone recognizes itself (#40157)
* feat(dictation): remove filler words from text the phone recognizes itself

Phones that dictate with their own recognizer (Automatic or This phone)
never send text through the computer, so its filler pass never saw it.
The page's on-device speech adapter now runs the same shared text
pipeline on the phone's live and final text, in the language of the
locale the recognizer started in, and honours the computer's Remove
Filler Words switch, which the host now reports in its dictation setup.
An older host that doesn't report it leaves the switch on, its default.

* test(mobile): expect both commas to go around a mid-sentence filler on the phone too
2026-11-09 07:01:42 +00: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
Neil 83f8e6340d refactor(shared): organize file operations and storage owners (#39746) 2026-11-07 22:58:35 -08:00
Kelvin Amoaba a18165e046 fix(mobile): make the device store's size accounting and page writes safe (#39408)
Count a key changed twice in one write once, keep the per-bucket estimate an upper bound, and redo a seed pass that missed files at the next foreground instead of trusting it as exact.

The page store refuses a bad key or an over-cap value before posting anything, keeps its calls in call order and inside the bridge's in-flight cap, and checks deferred slots. The shell reads only the keys that surely fit the reply budget, so no value is decrypted twice.
2026-11-07 22:56:59 +00:00
Kelvin Amoaba 7234301afb fix(mobile): finish Android dictation on a call, alarm or leaving the app (#39492)
* fix(mobile): finish Android dictation on a call, alarm or leaving the app

A transient audio-focus loss (call, alarm, assistant) left the mic recording
silence, and pausing the activity closed the mic only to reopen it on resume,
splicing a silent gap into the dictation. Both now end the recording and emit
an interruption, so dictation finishes and inserts what was heard. The
dictation hook also finishes when the app goes to the background, which
covers iOS and shells without this native change.

* fix(mobile): keep a dictation that is waiting on the Android mic prompt

* fix(mobile): keep Android recording state consistent across the focus and JS threads

* refactor(mobile): name the Android pause path for what it does and stop retaking focus on resume

* fix(mobile): keep what the open mic heard when leaving during a pending host start

* fix(mobile): close the open mic at once when leaving during a pending host start

* fix(mobile): a second page capture end waits for the stop already in flight
2026-11-07 13:30:50 +00:00
Kelvin Amoaba 5dae65c4b4 fix(mobile): treat a slow phone speech service as busy, not unsupported (#39489) 2026-11-07 12:36:51 +00:00
OrcaWinandOrcaWin 3ca9cb8bc2 test: remove 242 low-value tests (#39487)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-07 04:36:43 -08:00
Kelvin Amoaba 9ea9ea9a19 fix(mobile): show the phone speech download size and drop a cancelled session's late text (#39479)
* fix(mobile): show the phone speech download size and drop a cancelled session's late text

* fix(mobile): show the Android language download size too

* fix(mobile): keep a recognizer error raised while its start resolves, and read the download size aloud
2026-11-07 12:07:17 +00:00
OrcaWinandOrcaWin 92ef9440db test: remove 221 low-value cloud, mobile and journal tests (#39449)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-07 02:12:41 -08:00
Kelvin Amoaba ffaf887e78 feat(mobile): transcribe dictation on the phone, with the computer as fallback (#39386)
* feat(mobile): define the on-device speech contract for the native audio module and page bridge

* feat(mobile): dictate on the phone first and replay to the computer when the phone fails

* refactor(mobile): type the on-device speech module without a cast

* fix(mobile): point dictation's finish ref at the committed callback

* test(mobile): wait on the takeover request instead of a fixed sleep

* fix(mobile): release each dictation request's own share of a replayed backlog

* fix(mobile): let the computer's text replace the phone's after a fallback
2026-11-07 09:37:45 +00:00
Kelvin Amoaba 64d811bde0 feat(mobile): send phone dictation audio every 150 ms with at most four chunks in flight (#39341)
Each chunk RPC holds one of the page bridge's 60 desktop request slots until
the host answers, through a reconnect too, so the page drained the microphone
only every 500 ms. Cap chunk sends at four per dictation and merge audio
captured meanwhile into the next request, then drain every 150 ms.
2026-11-07 07:25:10 +00:00
OrcaWinandOrcaWin f5f45784e2 test: remove 212 low-value mobile shell and routing tests (#39334)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-06 23:07:50 -08:00
Brennan BensonandGuderlilian dbf56346e8 Keep phone chat menus above the keyboard (#38834)
Slash and mention suggestion menus in the phone chat composer stay reachable above the on-screen keyboard while typing.

Co-authored-by: Guderlilian <73724370+qq2144@users.noreply.github.com>
2026-11-06 15:05:05 -08:00
Kelvin Amoaba f76e6eebda perf(mobile): stop live input and keyboard height re-rendering the whole session (#39032)
* perf(mobile): stop live input and keyboard height re-rendering the whole session

* refactor(mobile): drop the web soft-keyboard state hook nothing reads

* refactor(mobile): read the session keyboard lift from the shared occlusion hook

* test(mobile): give the command dock render probe a live input store
2026-11-06 18:17:31 +00:00
Kelvin Amoaba c884428609 feat(mobile): copy, save and share an image from the full-screen image viewer (#38303)
* feat(mobile): copy, save and share an image from the chat image viewer

* refactor(mobile): pass image viewer actions in so diagrams skip them

* fix(mobile): name the image verb native.image.act and serialize image actions

* fix(mobile): queue image actions per page and skip SVG links

* refactor(mobile): share the cache-folder helper and table the viewer's image actions

* fix(mobile): keep the toast's live region mounted so screen readers hear it

* test(mobile): re-record agent history goldens for the always-mounted toast region

* test(mobile): import the declared routes in the moved routes test
2026-11-05 22:44:36 +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
OrcaWinandOrcaWin b17646a5d9 test: remove 2191 low-value test declarations (#38113)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-04 03:40:25 -08:00
OrcaWinandOrcaWin 6792990b83 test: remove 1015 low-value test declarations (#38087)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-04 01:39:49 -08:00
OrcaWinandOrcaWin 74df8bf42e test: remove 997 low-value test declarations (#38058)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-03 23:59:28 -08:00
Neil 7bf0377072 refactor: place terminal and workspace contracts with concrete owners (#38061) 2026-11-03 22:49:34 -08:00
OrcaWinandOrcaWin e98c6a439a test: remove 2816 low-value test declarations (#38030)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-03 21:45:29 -08:00
Brennan Benson 40820c4c5c Open pasted text in structured chats (#35636)
* Open large pasted text and attached text in structured chats

* Read pending pasted text before its host route resolves

* Pass structured attachment eligibility from the owning chat

* Preserve composer and Markdown state when inspecting text attachments

* fix: preserve attachment identity and cancel deferred reads

* test: consolidate phone attachment rendering contracts

* Scope attachment previews to visible chats and share route indexes

* test: consolidate duplicate attachment preview coverage

* perf: share remaining workspace catalog derivations

* feat(chat): open text attachments from structured goal objectives

* fix(chat): reuse preview owner and bind app hooks

* refactor(chat): trim duplicate tests and unused capability initialization

* test(chat): share routing scope mount fixture

* Fix routing performance attribution and folder row imports

* Share attachment capability through its domain module

* Align attachment fixtures and warm routing contracts with current gates

* Preserve relay connection timeout default for ordinary requests

* Share image classification ownership and repair integration fixtures

* Repair real attachment integration fixture boundaries

* Expose e2e compiler diagnostics and prune stale read allowance

* Type the recall fixture row ref as a div

* Keep text attachment capability in its existing capability owner

* Keep image MIME bindings in the media type owner

* Own private bridge response completion at the request boundary

* Complete bridge fixture return and retention types

* Localize native chat text attachment preview controls

* Complete attachment preview localization at presentation boundaries

* Preserve legacy preview locale identity and complete localization controls

* Fix typed mobile host witness lookup

* Commit attachment page edits and reset mobile page scroll

* test(chat): remove duplicate preview localization coverage

* fix(mobile): apply page input font and footer safe area

* fix(chat): commit edited page before admitted navigation

* fix(chat): retain field readiness on pending commit

* fix: preserve attachment field focus until control activation

* fix: restore attachment preview styles and canonical close

* Bind mobile input font role to the central theme

* Type font source fixture cases as tuples

* Attribute inherited owner filter work and qualify folder fixtures

* Keep owner filter fixture input types source-derived

* test: retain attachment capability assertion import

* test: focus attachment coverage on important regressions

* Replace text attachment paging with bounded scrolling and trim tests

* Preserve literal phone attachment whitespace and trim unused test meter

* Keep scroll view refs and measurements out of render

* Keep preview collection independent of native clipboard initialization

* Give the phone scroll fixture coherent measured DOM geometry

* Commit attachment scroll extent before restoring its anchor

* Preserve text viewport geometry across bounded reads

* Unify bounded text scrolling around the viewport

* Preserve the live text anchor across viewport resizing

* Measure committed text viewport bounds from the host

* Preserve live attachment position across native client extent changes

* Use the actual first source block in the resize regression fixture

* Reuse subscription handle type

* Keep attachment effects keyed to their existing triggers

* Keep attachment rows within the committed track

* Allow the full attachment renderer contract to settle

* Open text attachment previews in a large modal

* Preserve attachment modal header layout with primitive-owned styles
2026-11-02 18:36:29 -08:00
Brennan Benson a1d30fbd77 fix(mobile): keep the keyboard open when a tab tap opens its details card (#36866)
* fix(mobile): keep the keyboard open when a tab tap opens its details card

Tracked in STA-13199.

* fix(mobile): keep the keyboard open when the session title opens its details card

The session title opens the same details card as a tab, but sat outside every
keep-focus container, so its tap moved focus off a focused composer or terminal
input and closed the soft keyboard. Attach the existing keep-focus helper to the
title button so the tap leaves the field focused, as tab taps already do.

* fix(mobile): keep the keep-focus helper safe where there is no DOM

The session title now attaches the keep-focus helper, and the title renders in
renderers without a DOM, where checking against HTMLElement throws. Check that
HTMLElement exists first, as other mobile code already does.

* test(mobile): use a type-only namespace import for the react-native mock type
2026-11-01 19:22:42 -08:00
Kelvin Amoaba 397d4443bd fix(mobile): keep focus when Android hides the keyboard for a tapped autocorrected word (#36947) 2026-11-01 15:40:25 +00:00
Kelvin Amoaba 4e2fcfe99c fix(mobile): send iPhone library photos as JPEG named .jpg, not HEIC named .png (#36989)
* fix(mobile): save iPhone library photos as JPEG named by their bytes

The iOS photo picker handed back the asset's HEIC bytes as-is, and the host
named every pasted image .png, so agents read a HEIC file as a PNG and failed.
Ask the picker for the compatible representation (JPEG), and name pasted
images by their signature so the extension always matches the bytes.

* fix(mobile): keep unknown pasted bytes on the .png name

A .heic name falls outside the shared image MIME table, so chat previews
and agent prompts would drop the image. The picker now sends JPEG, so
leave HEIC detection out.

* refactor(mobile): keep the pasted image extension list module-private
2026-11-01 10:32:11 +00:00
Neil c433d58f5c test(mobile): count dictation refusals before the slot probe fills the bridge (#36938)
The free-slot probe fills every desktop slot, so end()'s final chunk forward
is refused by construction. Since #36922 reserved native slots, that final
read now succeeds and its forward is refused, failing Mobile verify under Bun.
2026-11-01 01:04:49 -07:00
Kelvin Amoaba 5eac01e224 fix(mobile): keep bridge slots for photo picks when desktop calls stall (#36922)
Desktop RPCs and on-device native verbs shared the bridge's 64 in-flight request slots on both page and shell. Unanswered desktop calls could hold all of them, refusing native.media.pick and native.media.release; refused releases stranded staged handles until expiry, so later picks hit native_media_handle_cap. Desktop calls now stop at 60 so native verbs always have the last 4.
2026-11-01 07:34:46 +00: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
OrcaWinandOrcaWin cde2472a83 fix(mobile): refuse PDF opens from hidden pages (#34869)
* fix(mobile): refuse PDF opens from hidden pages

* test(mobile): assert one refused hidden PDF open instead of scaled loops

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-28 20:07:42 -07:00
Kelvin Amoaba e5b45ac90f fix(mobile): keep dictation recording through a reconnect and keep what was already said (#35338)
* fix(mobile): keep dictation recording through a reconnect

The host tied a phone's dictation to its socket, so any reconnect cancelled
it, and the phone ended the recording as soon as the connection dropped.
The host now owns the session by device and waits a grace period for the
phone to come back. The phone keeps recording through the reconnect and
keeps the text transcribed so far if the connection does not return.

Fixes #35211

* fix(mobile): bound dictation reconnect waits and release retired relay waiters

* fix(mobile): resend an unsent dictation finish after a connection move and send the text so far only when it changes

* fix(mobile): hold dictation requests through a suspended relay and bound the start wait

* fix(mobile): recognise a suspended relay client across the page bridge

* refactor(dictation): refresh one abandon timer, report text by version and share the reconnect wait

* fix(mobile): resend dictation text each second and never wait offline for a cancel
2026-10-28 22:27:21 +00:00
Kelvin Amoaba 7951f8fe51 fix(mobile): keep dictated words through calls, busy taps and failed inserts, and say why dictation failed (#35216)
* fix(mobile): keep dictated words through interruptions, busy taps and failed inserts

A call, Siri or mic dropout now finishes the dictation instead of
discarding it, a tap while transcribing no longer cancels, a transcript
its target refuses is copied to the clipboard with a toast, and host
dictation error codes show as plain sentences.

* test(mobile): share one session dictation harness for refusals and kept transcripts

* refactor(mobile): share the lost-session dictation sentence and keep speechless helpers private

* fix(mobile): keep a dictated terminal transcript when the live send throws
2026-10-28 17:34:33 +00:00
Kelvin Amoaba 247035b026 fix(mobile): give phone audio back when dictation stops, and fail clearly when iOS can't record (#35214)
* fix(mobile): release the dictation audio session on stop and fail clearly without iOS voice processing

Stopping dictation only muted the native input, so the iOS voiceChat session
and Android audio focus stayed held until the screen unmounted and other apps'
audio stayed ducked. End now tears the engine down; the next open rebuilds it.
iOS tearDown stops I/O before deactivating and notifies other apps.

The iOS engine returned from setup before installing the mic tap when voice
processing could not be enabled, so recording reported success and captured
nothing. Setup now throws, so initialize fails and the phone shows the
microphone error.

* test(mobile): expect dictation stop to tear the audio engine down

* test(mobile): drop the duplicate release-throw case from native capture tests
2026-10-28 17:15:30 +00:00
OrcaWinandOrcaWin 72ff417691 fix(mobile): discard refused picker cache copies (#34772)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 23:18:40 -07:00
OrcaWinandOrcaWin 4270c886d8 fix(mobile): release native picks after page teardown (#34760)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 23:18:36 -07:00
OrcaWinandOrcaWin 9c094e16d2 fix(mobile): share microphone ownership across page sessions (#34762)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-10-27 23:18:27 -07:00
zhangxaochenandKelvin Amoaba 8291297b0b fix(mobile): recover terminal input lease on attach and preserve picked file names (#32987)
Co-authored-by: Kelvin Amoaba <97001695+AmoabaKelvin@users.noreply.github.com>
2026-10-26 22:34:31 +00:00