Repository navigation
feat(mobile): distinguish remote and terminal instances - #5685
Merged
Merged
Conversation
This was referenced Aug 29, 2026
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (87 files)
Previous Review Summaries (4 snapshots, latest commit 26dddff)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 26dddff)Status: No Issues Found | Recommendation: Merge Files Reviewed (1 files)
Previous review (commit f97ab91)Status: No Issues Found | Recommendation: Merge Files Reviewed (2 files)
Previous review (commit 388c251)Status: No Issues Found | Recommendation: Merge Files Reviewed (10 files)
Previous review (commit 56d55f0)Status: No Issues Found | Recommendation: Merge Files Reviewed (10 files)
Reviewed by grok-4.6 · Input: 349.2K · Output: 13.4K · Cached: 305.8K Review guidance: REVIEW.md from base branch |
4 of 6 tasks
eshurakov
approved these changes
Sep 1, 2026
This was referenced Sep 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
InstancePickerInstancealias takes each normalized row fromMobileRouter.activeSessions.listInstances, so picker callers share the router's metadata and capability contract. The former hand-written subset is removed; constructed instances must include every required router field.InstancePickerBridgekeeps its selection contract, includingnullfor Cloud Agent.Files
apps/mobile/src/lib/picker-bridge.ts— Source; M; +5/-13. ImportsinferRouterOutputsandMobileRouterto derive the complete instance type for the bridge.apps/mobile/src/components/agents/new-session-configure-form.test.ts— Test; M; +3/-0. Updates the new-session configuration tests.apps/mobile/src/components/agents/use-remote-spawn-dispatch.test.ts— Test; M; +6/-0. Updates the remote dispatch tests.apps/mobile/src/lib/remote-spawn-admission.test.ts— Test; M; +3/-0. Updates the remote admission tests.apps/mobile/src/lib/remote-submit-outcome.test.ts— Test; M; +8/-1. Updates the remote submit outcome tests.apps/mobile/src/lib/resolve-live-instance.test.ts— Test; M; +6/-5. Updates the live-instance resolution tests.dedupeInstanceLabelsaccepts an optional locale, defaults toi18n.language, and returns requiredLabeledInstance.displayFactsandtestIDwithout dropping or reordering connections. Branches truncate after 20 Unicode code points; localized start dates include minutes, anddisplayFactsjoins available fields with a middle dot.dedupSuffixnow marks only matching displayed identities; suffixes and stableinstance-picker-row-identifiers use six-character hexadecimal connection hashes.Files
apps/mobile/src/lib/instance-picker-rows.ts— Source; M; +46/-36. Compares a JSON tuple of kind, name, project, and displayed facts; every colliding peer receives a suffix. Missing facts stay absent; shortened branches gain an ellipsis, and dates include year, short month, day, hour, and minute. Row identifiers remain independent of facts, duplicate status, and order.apps/mobile/src/lib/instance-picker-rows.test.ts— Test; M; +165/-4. Updates the instance-row tests.PickerListItemseparates headers from selectable connections: Cloud Agent stays first, followed by nonempty Remotes and Terminals groups.InstancePickerScreenadds kind icons, wrapping text, separate#suffixes, and localized radio labels containing the group, identity, and available facts. Selection still usesconnectionId, clears the bridge, and closes the sheet; loading, retry, refresh, and polling keep their existing behavior.Files
apps/mobile/src/app/(app)/agent-chat/instance-picker.tsx— Source; M; +59/-18. Addsheader:<kind>keys, connection keys, stable row identifiers, accessible headers, and language-sensitive lists. Keeps theradiogrouplist directly insidePickerSheetfor native sizing.apps/mobile/src/components/agents/instance-picker.mounted.test.tsx— Test; A; +314/-0. Adds a mounted test file for the picker.SheetHeaderlets the row grow and wrap, separating Share and Cancel instead of placing both controls at one absolute position. Buttons gain minimum dimensions and centered content; the title allows two lines with end truncation and exposes its fullaccessibilityLabel. Existing callers keep the same props, callbacks, disabled controls, and Share busy state; native direction andms-autoalign the leading and trailing actions.Files
apps/mobile/src/components/sheet-header.tsx— Source; M; +23/-22. Adds gaps, width caps, growing title space, andmin-h-11/min-w-11controls; retainscollapsable={false}before scroll content.apps/mobile/src/components/sheet-header.mounted.test.tsx— Test; M; +224/-13. Updates the mounted header tests.INSTANCE_GROUP_LABEL_KEYSlinksremotetoagentChat.instancePicker.remotesandclitoagentChat.instancePicker.terminals. The source labels are “Remotes” and “Terminals”; the translation pass adds both labels to 86 other catalogs. These two keys contribute 174 labels across 87 catalogs without adding a setup requirement.Files
apps/mobile/src/i18n/locales/en.json— Source; M; +2/-0. Adds the two authored group labels and retains all existing keys and values.Tests: 1 file added and 7 modified (+729/-23):
instance-picker.mounted.test.tsx,sheet-header.mounted.test.tsx,instance-picker-rows.test.ts,new-session-configure-form.test.ts,use-remote-spawn-dispatch.test.ts,remote-spawn-admission.test.ts,remote-submit-outcome.test.ts, andresolve-live-instance.test.ts.Generated: 86 non-English
apps/mobile/src/i18n/locales/*.jsoncatalogs modified (M; +3/-1 each, +258/-86 total); 2 keys add 172 translated labels.Verification
Local end-to-end verification on an iOS simulator, 2026-09-01. Seven of nine checks passed. Two have partial coverage.
This section covers the stack's six PRs together: #5666, #5668, #5677, #5680, #5685, and #5686.
No product bug was found. No product source changed. The worktree stayed clean.
#77537band#481fd3on separate lines.Remotes and locale evidence
The installed CLI 7.5.6 reports no
kind, so every real relay lands under Terminals and the Remotes group is unreachable through it. A stand-in producer therefore attached over the real CLI WebSocket contract (/api/user/cli,instanceSchemainservices/session-ingest/src/types/user-connection-protocol.ts) and heartbeat an instance identity. Everything below the CLI process is the shipped path: the durable object,getConnectedInstances,activeSessions.listInstances, and the picker.Two
kind: 'remote'instances and onekind: 'cli'instance produced:Cloud Agent, thenREMOTESwith both remote rows, thenTERMINALSwith the terminal row.feature/remotes-verify1is 23 code points and rendered asfeature/remotes-veri…, exactly the documented 20-code-point boundary.startedAtrenderedmainalone, with no separator and no date.Started Sep 1, 2026 at 7:51 AM. German renderedGestartet 1. Sept. 2026, 07:51— day-first, German month, 24-hour clock.REMOTESbecameREMOTE-INSTANZENin German.Remotes, ci-runner-eu-west on cloud, and feature/remotes-veri… · Started Sep 1, 2026 at 7:51 AM.instance-picker-row-3c7b01,-fe6b0a, and-377bcdwere byte-identical across both locales, so the identifier does not depend on displayed facts.Run on: ci-runner-eu-west · cloud.Untested condition
The offline banner is driven only by NetInfo device connectivity.
createOfflineBannerStorecommitsonlineas soon as NetInfo reports a connection and runs its HTTP probe only to suppress a false NetInfo offline report (apps/mobile/src/lib/offline-banner-state.ts:67-88). A backend-only outage with the device still online therefore shows no banner by design. A real device-wide outage was not simulated, so that path has no runtime verdict.Setup
mobile-ux-ad6d-s6, simulator iPhone 17 Pro on iOS 26.5.xcrun simctl io <udid> screenshot./Users/igor/Projects/.scratch/local-e2e-ux/.Unrelated observation
After "Allow once" on a tool permission, repeated Back taps did not leave the chat screen; a cold restart restored navigation. Evidence:
/Users/igor/Projects/.scratch/local-e2e-ux/C-back-stuck.png. None of these six PRs touch navigation, and the symptom was not reproduced in a second round. It needs a real CLI relay executing a command to reproduce, so it is recorded here rather than diagnosed.