Commit Graph
464 Commits
Author SHA1 Message Date
Neil 17a1dc373b refactor: group shared worktree modules by feature (#42093)
* refactor: group shared worktree modules by feature

* refactor: retarget new worktree admission test to moved owner
2026-11-13 10:59:36 -08:00
OrcaWinandOrcaWin 8e604e2f57 test: trim duplicate mobile and internal fixture assertions (#42094)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-13 10:27:01 -08:00
OrcaWinandOrcaWin b1fefd9fcd test: remove low-value mobile Markdown editor coverage (#42090)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-13 10:06:48 -08:00
OrcaWinandOrcaWin 048eefd3bf test: remove low-value mobile and example coverage (#42087)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-13 09:55:11 -08:00
Neil dc67a6435f refactor(mobile): organize source control by feature owner (#42073) 2026-11-13 08:49:09 -08:00
Neil e956498414 refactor(mobile): organize terminal modules by responsibility (#42040) 2026-11-13 06:37:45 -08:00
Neil c2deee70df refactor(mobile): organize platform adapters by capability (#42030) 2026-11-13 05:54:19 -08:00
Neil 8dd3b71090 refactor: organize mobile files and host-screen domain owners (#42019) 2026-11-13 05:10:41 -08:00
OrcaWinandOrcaWin 35e0f9a9f2 test: remove route forwarding and internal mobile marker cases (#41900)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-13 00:26:28 -08:00
OrcaWinandOrcaWin fd8c3da20a Simplify delete dialogs and make button states visible (#41870)
* fix: simplify delete dialogs and clarify control interaction states

* fix: preserve bulk delete context and update dialog e2e flows

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-13 00:12:38 -08:00
Jinjing a1667c0297 Open launched agents from mobile AI actions (#35235) 2026-11-12 19:45:35 -08:00
Brennan Benson 91b3f12f03 perf(git): reuse branch snapshots across searches (#41558)
* perf(git): share branch snapshots across repository searches

* fix(git): read branch occupancy and current checkout live

* Preserve branch occupancy and unborn checkout parity

* Keep native searches for clients without qualified refs

* fix(git): preserve compiled branch option caching

* fix(git): derive selected source labels from branch identity

* test(git): resolve selected source fixture import

* fix(git): keep branch default menu translations reactive

* test(git): type mobile branch row mock parameters

* fix(git): keep branch metadata expiry bounded during streaming
2026-11-12 15:12:55 -08:00
Jinjing d1ae177242 feat(mobile): floating answer card, queued messages above it (#41611)
* feat(mobile): floating answer card, queued messages above it

Port of stablyai/orca-private#724 (e1a794e6), plus:
- keep orca #40820's filled Steer pill on the lit head row
- let the open queue list shrink and scroll under a height limit so
  the Show less row stays whole at 320pt on a short screen

* test(mobile): pin the short-screen queue shrink at narrow width and on the box

* fix(mobile): scroll a failed queued message into view and keep the lit Steer pill's press

- A failure that opens the queue scrolls its row into view, so on a short
  screen the reason the list opened is visible above Show less.
- The pressed opacity comes after the lit fill on the Steer pill.
- Test the lit pill (orca #40820) and the failure scroll.

* fix(mobile): place a failed queued row only from its fresh height and let stale requests lapse

- The failure scroll waits for the failed row to lay out again, then settles
  on the known heights after 300ms, so a stale height or an unresolved
  request never moves the list later.
- A deferred show expires after 1s and on a queue change; the inline
  editor's reveal scrolls at once again.

* refactor(mobile): keep the failure-scroll request as the queue list's own state

React Doctor reads a hook-returned setter called during render as a prop
callback; the list now owns the request with useState and hands it to the hook.

* fix(mobile): address review threads on the queued list

- Fold again for a later prompt: an open choice made in one placement no
  longer comes back in the next.
- Scroll a message the person queues into a folded list into view through
  the same deferred show as a failure.
- Lift from the row only in the plain presentation; a settings row keeps
  its grip gesture.

* fix(mobile): let a choice made in the render a prompt arrives win over the placement reset

* fix(mobile): count an open inline editor's height when placing a later queued row

* test(mobile): note why the inline-editor test stub is cast
2026-11-12 11:11:28 -08:00
OrcaWinandOrcaWin d34c829237 test: retire low-value draft, crypto, and lifecycle coverage (#41614)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-12 10:02:35 -08:00
Neil fb8d6f950b refactor(github): organize concrete feature owners (#41601) 2026-11-12 09:17:26 -08:00
OrcaWinandOrcaWin c0d4b77a6f test: remove low-value mobile formatting and adapter suites (#41495)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-12 02:35:37 -08:00
Neil 176943e8fe refactor(mobile-tasks): group modules by concrete feature owners (#41410)
* refactor(mobile-tasks): group modules by concrete feature owners

* refactor(mobile-tasks): consolidate concrete owner imports

* refactor(mobile-tasks): point recording loaders at concrete owners
2026-11-11 22:40:18 -08:00
Brennan Benson 7d9290ee8d fix(native-chat): keep Send's round size while Cmd/Ctrl previews steer (#40820)
Holding Cmd/Ctrl swapped the round Send/Stop button for a wide labeled pill,
pushing the model picker, context ring and mic left. The preview now keeps
Send's round button and only swaps its icon (CornerDownRight for steer,
ListEnd for queue); the label stays as the aria-label. With Steer queued,
the head queued card's Steer button also fills as the primary.

The phone composer had the same pill and now follows the same rule.
2026-11-11 22:00:14 -08:00
Kelvin Amoaba c5e82a637d feat(mobile): show only the open tab, with a tab count and a sheet of every tab (#41345)
* feat(mobile): show only the open tab, with a tab count and a sheet of every tab

The session bar shows the open tab at full width, then a tab count cell and a + cell. The count opens a sheet of every tab grouped Needs you / Working / Everything else; tapping the tab opens its actions; swiping it steps between tabs; + opens a new tab sheet with agents as tiles. The header subtitle shows the branch. Brings back #40592 on current main.

* fix(mobile): don't switch tabs when a bar swipe is interrupted
2026-11-12 04:45:20 +00:00
OrcaWinandOrcaWin 7bafdc9f0f test: remove low-value browser, image, and ACP suites (#41329)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 18:30:07 -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
Brennan Benson aa6b4197b8 fix(chat): keep generated images visible with the final answer (#40935)
* fix(chat): keep generated images with settled answers

* fix(chat): deduplicate images against rendered Markdown

* Keep generated answer previews aligned with rendered Markdown

* Keep generated-image regressions in the existing rendered transcript suite

* Keep generated image renderer fixtures within their project boundary
2026-11-11 13:29:04 -08:00
OrcaWinandOrcaWin 54912d99dc test: remove 37 low-value cases and five whole suites (#41223)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 11:20:35 -08: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
OrcaWinandOrcaWin 9576e55773 test: remove 1,144 low-value declarations (#41177)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 09:11:06 -08:00
OrcaWinandOrcaWin 7d92d106f4 test: remove 168 low-value tests across eleven suites (#41108)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-11 01:59:49 -08:00
Kelvin Amoaba 01efbf8cd1 feat(mobile): show merged, closed and draft PR icons by state (#40921)
* feat(mobile): pick the PR glyph from PR state

Workspace rows always drew the open-PR glyph and only changed its color,
and the PR tab's state badge had no glyph. Both now show merged, closed and
draft glyphs, from one prStateIcon mapping that the details sheet and task
rows also use.

* feat(mobile): show the PR state on the session header's source-control button

The button always drew a branch glyph. When the worktree's catalog row has a
linked PR it now draws that PR's state glyph in its state colour, read from
the host list's worktree.ps query in its own component.

* fix(mobile): read the header's PR state from the catalog cache only

Opening a session must not request worktree.ps before its first paint, so the
source-control button reads what the host list last loaded instead of
fetching it.
2026-11-11 04:25:41 +00:00
Kelvin Amoaba dbd3454ee1 feat(mobile): GitHub-style diff rows with a pinned gutter and sideways scroll (#40961) 2026-11-11 04:18:55 +00:00
Kelvin Amoaba aba6ec4c4c feat(mobile): GitHub syntax colours and the system code font for code, files and diffs (#40942) 2026-11-11 04:17:12 +00:00
Kelvin Amoaba c58ffc0042 revert(mobile): restore the scrolling session tab strip (#40938)
Reverts #40592 (12e809c755). The session bar goes back to the scrolling strip of tab cells, the + menu goes back to the action sheet, and the header subtitle shows the tab count again.
2026-11-11 00:41:08 +00:00
Jinjing a7a21c8658 Source Control menu: one line per row with a short status (#40919)
* Show Source Control menu rows on one line with a short status

* Keep Push and Force Push clickable; force push shows remote-only commits it replaces

* Match Force Push description to remote-only commits; list review blockers exhaustively

* Show short statuses for every blocked review action
2026-11-10 16:40:17 -08:00
Neil b5611915f9 refactor(mobile): group usage and shell generation owners (#40783)
* refactor(mobile): group usage and shell generation owners

* refactor(mobile): use direct module types in reset credit adapter
2026-11-10 14:28:58 -08:00
Kelvin Amoaba 12e809c755 feat(mobile): show only the open tab, with a tab count and a sheet of every tab (#40592)
* feat(mobile): show the open tab as one pill with a tabs sheet

The phone copied desktop's tab strip, which fits about three tabs cut to
~95 pt and hides a tab that needs you behind an edge dot. The bar now shows
only the tab you're in, at full width, with the tab count. Tapping it opens
a sheet of every tab grouped by what needs you, with each tab's state and
last activity; swiping it steps to the next tab. The + sheet shows agents as
a grid above Terminal, Browser and Markdown note, and the header names the
branch instead of the tab count.

* feat(mobile): pair the tab count with + and open tab actions from the pill

The count and its chevron inside the pill read like a menu and hid the
"another tab needs you" dot. The count now shares a capsule with +, the
way phone browsers put the tab-count button beside new tab, and tapping
the pill opens the tab's own actions.

* feat(mobile): give the tab count its own button beside +

The shared capsule made each half a small target. The count is now a
round nav button like +, lined up under the header's buttons.

* feat(mobile): draw the tab bar as the strip's square cells

The rounded pill and round buttons read as a different control from the
strip people know. The open tab is now the strip's raised, underlined cell
from the screen edge, with the count and + as square cells in the same
row, which also gives them 46x44 pt targets.

* fix(mobile): keep a hairline after the tab bar's last cell in the top bar
2026-11-10 15:32:40 +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
Neil 50e265e6af refactor(mobile): finish native chat owner and test lifecycle cleanup (#40710) 2026-11-10 01:11:28 -08:00
OrcaWinandOrcaWin 6231ca5695 test: remove low-value fixtures and duplicate cases (#40667)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 22:41:27 -08:00
Brennan Benson 8573f7ce86 Create a worktree per repository from an empty folder workspace on the phone (#40139)
* feat(mobile): create a worktree per repository from an empty folder workspace

A folder workspace with no attached worktrees lists one card per
repository in its project group, as desktop's empty state does. Tapping
one creates a worktree named after the folder, attached to it, in place;
a taken name or a setup choice opens the new-workspace composer with the
repo, the name and the folder parent filled in. Shown only when the host
creating it supports exact-name creation.

* chore(mobile): merge the folder repo read's execution-host imports

* fix(mobile): folder creates keep their repository until the folder shows them

Every create from a folder's empty state, direct or through the
composer, holds its repository from admission until the folder lists
the new worktree, so a lost reply, a remount or a reopened form can't
start a second one. The composer and toasts belong to the folder
screen, stay on the folder's host, and say nothing once it's left. A
relayed server's repository read holds no desktop event stream, and a
failed read can be retried.

* test(mobile): a folder create resent after a lost reply carries the same mutation id

* fix(mobile): folder creates keep their name, and a left or replaced form shows and holds nothing

* fix(mobile): pause folder rows under the create form; a lost folder create is checked, never resent as another

* fix(mobile): a folder card never resends a form's create, and one form owns the folder screen at a time

* fix(mobile): a folder setup choice resends only its own unconfirmed create, and the newest form silences older ones

* test(mobile): declare the submit hook's folder launch in its recording fixture

* fix(mobile): a create refused on a resend after a lost reply tries no other name and stays unconfirmed

* fix(mobile): a replayed refusal after an agent-launch fallback stops the retry, and the composer says it may have been created

* test(mobile): type the replayed refusal reply in the retry test

* ci: retrigger checks

* fix(mobile): localize the folder and uncertain-create messages in the workspace composer
2026-11-09 17:18:33 -08:00
Kelvin Amoaba 854928969e feat(mobile): add Shift, Ctrl and Alt latches and opt-in agent keys to the terminal key row (#38776)
* feat(mobile): smart rail keys for the terminal agent's state, with Shift/Ctrl/Alt latches

* fix(mobile): cancel key presses only when the key row really moves

* fix(mobile): keep Smart rail on through Reset Defaults and finish two-write keys

* fix(mobile): only a finger scrolling the key row cancels its presses

* fix(mobile): hold the smart group until the tap's press lands, and drop clicks on keys that moved

* refactor(mobile): simplify the smart rail touch hook and layout read

* chore(mobile): allowlist the Shift, Ctrl and Alt key names

* feat(mobile): Codex async question keys on the smart rail

* fix(mobile): drop the Codex Always key, whose key differs by approval

Codex binds "don't ask again" to p for a command-prefix rule and a for session and file approvals (0.136 through 0.166). The permission hook doesn't say which one is on screen.
2026-11-09 21:19:11 +00:00
Kelvin Amoabaandzhangxaochen 4783b08ae5 fix(mobile): close the details card when you touch the terminal (#38823)
* fix(mobile): close the details card when a touch lands outside it

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

* fix(mobile): explain the pointerdown listener and drop a focus check that can't fail

---------

Co-authored-by: zhangxaochen <3416677+zhangxaochen@users.noreply.github.com>
2026-11-09 20:12:31 +00: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
OrcaWinandOrcaWin 2eaba5b39e test: remove low-value VM, mobile, work-item and terminal suites (#40376)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-09 06:31:53 -08:00
Kelvin Amoaba 7f63600a23 feat(mobile): keep commit, PR and review drafts across app kills (#40114)
* feat(mobile): keep commit, PR and review drafts across kills

* refactor(mobile): build commit, PR and review drafts on the shared draft fields, and clear only the text that was sent

* fix(mobile): keep a toggle made during Write with AI, the edit note while its sheet closes, and a newer PR edit after an earlier save

* test(mobile): wait for the saved review note row instead of sleeping

* perf(mobile): keep a hash of the PR text an edit was typed against, not a second copy
2026-11-09 14:02:12 +00:00
Kelvin Amoaba e22bb7c46c feat(mobile): keep Tasks and new-workspace drafts across kills (#40127)
* feat(mobile): keep Tasks and new-workspace drafts across kills

Task comments (per item and project row), the New issue title and body,
and the New workspace note now live in device-store draft rows. They come
back after the form closes or the app is killed, and only into an empty
field. A comment's setter stays bound to its item, so a send that settles
after the user moved on clears the right row.

* fix(mobile): rebuild comment sends when the draft's item changes

* fix(mobile): key the workspace note by host and keep cleared fields cleared

* fix(mobile): clear only the note a finished create sent

* fix(mobile): count clearing an empty draft field as the user's choice

* perf(mobile): cap field drafts, read sheet drafts on open, retry a failed read once

* fix(mobile): retry a failed draft read after a pause and keep New issue text typed during a create

* fix(mobile): save draft text again once a failed store read can be retried

* fix(mobile): remove a stored draft when an unread field is cleared
2026-11-09 13:51:32 +00:00
OrcaWinandOrcaWin a489ef5ba3 test: reconcile approved test removals with current main (#40176)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-08 23:19:51 -08:00
OrcaWinandOrcaWin d714d577bf test: remove 45 low-value suites and redundant cases (#40072)
* test: remove low-value synthetic and duplicated cases

* test: remove low-value IPC and renderer cases

* test: remove marginal mobile web build helper cases

* test: remove marginal browser coverage

* test: remove low-value mobile coverage

* test: remove fixture inventories and diagnostic-only cases

* test: remove low-value shared test suites and matrices

* test: remove internal-work and mock-only coverage

* test: remove prose passthrough and scan-count assertions

* test: remove low-value renderer suites and copy counters

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-08 19:50:37 -08:00
OrcaWinandOrcaWin 2b89fa7c98 test: remove 61 low-value mobile tests (#39955)
* test: remove 61 low-value mobile tests

* test: use array shorthand in retry fixture

---------

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-08 12:31:33 -08:00
OrcaWinandOrcaWin b4f198379a test: remove 17 low-value mobile test cases (#39941)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-08 11:43:36 -08:00
Kelvin Amoaba 51c77320bc feat(mobile): mark agents read and clear them from the Agents tab (#39245)
Unread rows show the desktop's bell, swipe right toggles read, swipe
left clears a finished agent, and the long-press and options menus get
Mark read/unread, Unread only, Mark all read and Clear finished. Writes
go through agentActivity.setRead/clear and show optimistically until the
desktop's list confirms them.
2026-11-08 19:40:47 +00:00
OrcaWinandOrcaWin 4e70998609 test: remove 8 low-value test cases (#39934)
Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
2026-11-08 11:23:56 -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