Skip to content

feat(mobile): support Duo in the shared iOS app - #12648

Merged
juliusmarminge merged 21 commits into
mainfrom
mobile/duo-v5-stack
Oct 9, 2026
Merged

juliusmarminge merged 21 commits into
mainfrom
mobile/duo-v5-stack

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Sep 19, 2026 •

Copy link
Copy Markdown
Member

Problem

Duo needs to adapt between its folded phone layout and expanded workspace within the same iOS app. The previous app does not account for hinge and toolbar reservations.

Change

The shared v5 navigator now supports the iPhone Duo's folded and expanded layouts. UIKit owns column presentation and toolbar placement; the existing Expo app, React Navigation router, conversation selection, and composer drafts remain shared.

This adds iOS 27.1 fold/occlusion and vertical-toolbar metrics and keeps composers and bottom controls in a usable region. The same iOS binary detects UIKit hinge capability at runtime, including while Duo is folded. Ordinary iPhones retain their existing navigator and portrait policy; iPad retains its existing header controls, sizing thresholds, bubble widths, and scroll adjustment. There is no Duo build flag, EAS profile, or separate OTA channel. Use the existing preview and production profiles. All shared iOS profiles pin the EAS image macos-tahoe-26.6-xcode-27.1; the default SDK 58 image lacks the Duo UIKit APIs. The native APIs require a new binary built with the iOS 27.1 SDK; an OTA cannot add them to an older binary. The Screens fork is pinned to 5.0.0-t3.8, which applies item axis behavior when UIKit creates header and search-placement items. The underlying v5/iPad migration has already landed on main.

Folded Home uses the phone's bottom Search/Filter/New Chat toolbar. Expanded Home uses the iPad-style sidebar header and a full-width search row. New Chat has its own rail group; rail Search appears only while the sidebar is hidden and uses the same reveal-and-focus action as keyboard Search. Settings navigator containers leave horizontal insets to their leaf screens so the toolbar reservation is applied once.

Scope and approval

Maintainer-authored work directed by Julius: add Duo support to the existing Expo app, preserve regular iPhone and iPad behavior, and prepare this PR for merge. The shared v5/iPad migration has already landed separately.

Verification

Before and after the expanded sidebar change:

Before After
Before: crowded sidebar header After: full-width sidebar Search and separate New Chat

Before and after the Settings inset correction:

Before After
Before: Settings squeezed by repeated horizontal insets After: Settings uses its available width

Built one unified iOS development client with the iOS 27.1 SDK and installed the same app bundle on Duo, iPhone 17 Pro on iOS 26.5, and 11-inch iPad on iPadOS 26.5. Verified identical installed bundle hashes. Checked ordinary-phone portrait lock, bottom Search, Settings push/back; iPad portrait/landscape, sidebar/inspector switching, and thread selection with Files open; Duo folded Home's bottom Search, expanded sidebar Search and separate New Task rail, Settings width, and conversation/draft retention through open, half-open, and closed poses. A folded cold launch now selects the native host after attached-window hinge detection and supplies the collapsed column before UIKit attaches it, preventing an empty screen.

Settings and New Task now use the same native metrics as the workspace when selecting card versus sheet presentation, including short regular-width Duo windows. The 47 layout and reserved-region tests pass after this correction. This selector correction has not received another simulator pass.

Mobile TypeScript, targeted lint, and 72 focused layout/reserved-region/stack/scroll-edge tests pass. React Doctor reports no issues in changed code. Earlier Opus 5.5 and Fable 5.1 adversarial review rounds returned approve with caveats after their concrete blockers were fixed. Hardware ⌘F reveal/focus and keyboard behavior on physical devices remain unverified.

The split host now allows the sidebar width to reach the fold rather than capping it at 380pt. Regression checks restored the iPad’s existing left-side New Chat/maximize group and visible-sidebar controls. Search reveal now belongs to the shared keyboard action, and native column support handles patch-version strings.

13-inch iPad: sidebar, conversation, and Files inspector

Regular iPhone conversation

Recording: switching threads with the Files inspector open on 13-inch iPad

New Task before New Task after
Before: rail reserved twice After: full width beside the rail

Half-open Duo with sidebar aligned to the fold

Final unified binary verification:

Duo folded Home with bottom Search

The same binary expanded with the retained draft

Duo Settings in the same binary

11-inch iPad sidebar, chat, and Files in the same binary

Recording: folded Duo cold launch reaches Home

Built with GPT-6.1-sol through the Codex harness in T3 Code.

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Sep 19, 2026
@juliusmarminge
juliusmarminge added this pull request to stack #12649 September 19, 2026 22:56
@github-actions github-actions Bot added the 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. label Sep 19, 2026
@github-actions

github-actions Bot commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 4.9 KiB 5.0 KiB +23 B (+0.5%) 6.8 KiB ✅
Codex Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.2 KiB 1.2 KiB +23 B (+1.9%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 20.8 KiB 20.9 KiB +41 B (+0.2%) 29.3 KiB ✅
Codex Live turn messages 1 2 +1 (+100.0%) 8 ✅
Claude Total thread wire 5.0 KiB 5.0 KiB −24 B (−0.5%) 6.8 KiB ✅
Claude Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.2 KiB 1.2 KiB −24 B (−2.0%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 21.2 KiB 21.2 KiB −41 B (−0.2%) 29.3 KiB ✅
Claude Live turn messages 2 1 −1 (−50.0%) 8 ✅

Baseline: 29980a3 · PR result: 71c3f0d · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@juliusmarminge
juliusmarminge force-pushed the mobile/duo-v5-stack branch 2 times, most recently from 3f80f56 to 2669f8d Compare September 19, 2026 23:31
@juliusmarminge
juliusmarminge force-pushed the mobile/duo-v5-stack branch 8 times, most recently from 8b56c0e to 5b715dc Compare September 23, 2026 06:13
@github-actions github-actions Bot added size:XXL 1,000+ changed lines (additions + deletions). size:L 100-499 changed lines (additions + deletions). and removed size:XL 500-999 changed lines (additions + deletions). size:XXL 1,000+ changed lines (additions + deletions). labels Sep 30, 2026
@juliusmarminge
juliusmarminge force-pushed the mobile/duo-v5-stack branch 2 times, most recently from be6cffd to d7eb6a0 Compare September 30, 2026 18:36
@juliusmarminge

Copy link
Copy Markdown
Member Author

Addressed the short-Duo root presentation mismatch in b8969e0. Settings and New Task now select presentation using the same shared native metrics as the workspace. Focused tests, typecheck, lint, and React Doctor pass. The PR description now follows the template and records maintainer scope and verification. The walkthrough mentioning a Duo build flag/profile describes an older revision: the current app detects hinge support at runtime, shares one binary, and uses the existing OTA channels. Please assess the latest head.

@juliusmarminge

Copy link
Copy Markdown
Member Author

@coderabbitai The description warning is based on an obsolete diff. At b8969e0, T3CODE_IOS_DUO_BUILD, T3DuoEnabled, preview:duo, and preview-duo are absent. See the current app config and EAS profiles. The description accurately records one shared iOS binary and the existing OTA channels. This is maintainer-authored work explicitly directed and scoped by Julius in this T3 thread, not an external contribution requiring prior issue approval. Please refresh the walkthrough and description check against the current head rather than restoring the removed deployment split.

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail
git rev-parse HEAD
gh pr view 12648 --repo pingdotgg/t3code --json headRefOid,body
fd -t f '^(app\.config\.ts|eas\.json|NativeWorkspaceColumns\.ios\.tsx|T3NativeControlsModule\.swift|fingerprint\.config\.js)$' apps/mobile
ast-grep outline apps/mobile/app.config.ts
ast-grep outline apps/mobile/src/native/NativeWorkspaceColumns.ios.tsx
ast-grep outline apps/mobile/modules/t3-native-controls/ios/T3NativeControlsModule.swift
sed -n '1,240p' apps/mobile/app.config.ts
cat apps/mobile/eas.json
sed -n '1,100p' apps/mobile/src/native/NativeWorkspaceColumns.ios.tsx
rg -n -C 4 'hinge|supportsWorkspaceColumns|duoEnabled|T3DuoEnabled' apps/mobile/modules/t3-native-controls/ios/T3NativeControlsModule.swift
rg -n -C 2 'T3CODE_IOS_DUO_BUILD|T3DuoEnabled|preview:duo|preview-duo' apps/mobile docs/operations/mobile-screens-fork.md || true

Length of output: 21742


@juliusmarminge You are correct. I checked the current head, b8969e0c8a2, and the current PR description. I withdraw the obsolete description warning.

  • T3CODE_IOS_DUO_BUILD, T3DuoEnabled, preview:duo, and preview-duo are absent from the mobile code and Screens-fork guide.
  • Workspace-column support uses runtime hasHinge metrics, not a Duo build flag.
  • The EAS configuration retains the existing profiles and OTA channels.
  • The description records the shared iOS binary, native rebuild requirement, maintainer scope, and verification limits.

Thanks for clarifying the maintainer scope. The external-contribution prior-issue concern does not apply here.

I’m requesting a regenerated walkthrough and a fresh review against the current head. Neither should request restoration of the removed deployment split.


✏️ Learnings added
Learnt from: juliusmarminge
URL: https://github.com/pingdotgg/t3code/pull/12648

Timestamp: 2026-10-09T01:11:53.495Z
Learning: For pingdotgg/t3code PR #12648, the Duo deployment split was removed by b8969e0c8a2. apps/mobile/src/native/NativeWorkspaceColumns.ios.tsx detects phone workspace-column support using runtime hasHinge metrics. apps/mobile/app.config.ts and apps/mobile/eas.json do not define T3CODE_IOS_DUO_BUILD, T3DuoEnabled, preview:duo, or preview-duo. The design uses one shared iOS binary and existing OTA channels; do not request restoration of the obsolete deployment split.

Learnt from: juliusmarminge
URL: https://github.com/pingdotgg/t3code/pull/12648

Timestamp: 2026-10-09T01:11:53.495Z
Learning: pingdotgg/t3code PR #12648 is maintainer-authored Duo work explicitly directed and scoped by Julius in the T3 thread. It is not an external contribution requiring prior issue approval.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

⚠️ Action not completed

Incremental review skipped.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@juliusmarminge

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

🚀 Expo continuous deployment is ready!

  • Project → t3-code
  • Platforms → android, ios
  • Scheme → t3code-preview
  🤖 Android 🍎 iOS
Fingerprint 8c7fe5d4ac05e8883566cc5c3598298d04162ff8 1de91f8d4b5632288cd4a93c233fddc3a8abcd86
Build Details Build Permalink
DetailsDistribution: INTERNAL
Build profile: preview:dev
Runtime version: 8c7fe5d4ac05e8883566cc5c3598298d04162ff8
App version: 2.0.0
Git commit: bbe1fe37b7eb8664caeb14e730484d6071471328
Build Permalink
DetailsDistribution: INTERNAL
Build profile: preview:dev
Runtime version: 1de91f8d4b5632288cd4a93c233fddc3a8abcd86
App version: 2.0.0
Git commit: 71c3f0dfb0d1fd8c06bdb82dd27fc03bd6e6aa32
Update Details Update Permalink
DetailsBranch: pr-12648
Runtime version: 8c7fe5d4ac05e8883566cc5c3598298d04162ff8
Git commit: f086f1098fbd910dd808d1f631f4ce9921a0f031
Update Permalink
DetailsBranch: pr-12648
Runtime version: 1de91f8d4b5632288cd4a93c233fddc3a8abcd86
Git commit: f086f1098fbd910dd808d1f631f4ce9921a0f031
Update QR

@juliusmarminge

Copy link
Copy Markdown
Member Author

Fixed the failed cloud build in 71c3f0d. EAS auto selected an SDK without UIHingeInteraction, verticalBarEdge, or reservedRegions; the Swift compiler-version guard does not establish SDK availability. All shared iOS profiles now pin the documented macos-tahoe-26.6-xcode-27.1 image. EAS config resolves preview:dev to that image. A replacement preview:dev iOS build is being uploaded.

@juliusmarminge

Copy link
Copy Markdown
Member Author

The replacement preview:dev iOS build finished successfully on 71c3f0d with the pinned Xcode 27.1 image. This confirms the missing UIKit SDK symbols from the previous cloud build are resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews 🚀 Mobile Continuous Deployment Trigger Expo preview build 📱 Native Change Changes the native fingerprint; merging blocks production OTAs until a new store build ships. size:XL 500-999 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant