NewiPhone Duo, live in your browser. Try it →
Vibeview
Pricing
iPhone Duo · Automation

Set the iPhone Duo hinge angle from CLI, CI or an agent

Rokas Kašinskas — Co-founder, VibeViewPublished 2026-09-24Updated 2026-09-25

A foldable app has code paths that only run when the hinge moves: a layout that switches when the inner screen takes over, content that avoids the fold, an interaction that follows the hinge angle. Checking those by hand in Device Hub works once. Checking them on every change needs the fold to be something a script can do.

Why simctl can’t do it

The Duo simulator arrived with Xcode 27.1 beta, and its fold controls live in Device Hub’s toolbar, with an Option-key slider for the exact angle (SwiftLee). There is no matching simctl or devicectl command to set the angle, so everything headless is left out. The community has noticed:

  • Maestro has an open request, #3617, for a setFoldPosture command, because teams “can’t cover them in CI” today.
  • idb has #965: once the Duo is unfolded, idb ui tap and idb ui swipe still land on the outer display, so a script cannot touch the app on the inner screen.
  • hinge by Artem Novichkov is a local command-line tool that sets the angle on a booted Duo on your own Mac. It works by running a small helper inside the simulator, and its README is clear that the protocol underneath is private and undocumented, so it may break with future Xcode releases. If you have Xcode 27.1 on a Mac and want this locally, it is the tool to try.

The option below is different in kind: the Duo runs on VibeView’s Macs, and folding it is a supported command, from any machine with Node.js.

Fold the Duo from a terminal

You need the VibeView CLI (0.23.0 or later), an account, and a debug simulator build of your app in VibeView. For a React Native or Expo project, vibeview build --cloud --platform ios builds it in the cloud with no Mac, and it is ready to run on the Duo when it finishes (Cloud Builds). Cloud builds use a stable Xcode, so until Xcode 27.1 is out of beta a cloud-built app opens in a phone-sized window on the inner screen. That is enough to fold the device and check the cover screen; to test the full inner screen, build with Xcode 27.1 beta and add the build with vibeview upload-app. Any other simulator build can be uploaded the same way; see Preparing Your App Build.

  1. Install and sign in.

    npm install -g vibeview
    vibeview login
  2. Check the Duo is available. --models lists the device models you can start, and marks the Duo as foldable:

    vibeview list-devices --models
  3. Start a session on it. --detach keeps it running in the background and --json prints a session_ready event with the session id once the app is installed:

    vibeview dev --detach --json --platform ios --model "iPhone Duo"

    The session starts closed, on the cover screen. The event also carries a URL where you can watch the device fold live.

    vibeview dev is built around the React Native dev loop. For any other app, start an iPhone Duo session from the Sandbox instead and pass its session id to the commands below with --session; they work the same way.

  4. Fold it. A preset, or any whole angle from 0 (shut) to 180 (flat):

    vibeview set-posture partial --session <id>
    vibeview set-posture open --session <id>
    vibeview set-posture --angle 75 --session <id>
  5. Rotate it. Each call turns the device a quarter turn clockwise, in any posture; --degrees 270 turns it back a quarter and 180 turns it upside down:

    vibeview rotate --session <id>
    vibeview rotate --degrees 270 --session <id>
  6. Stop the session when you are done, so it stops using streaming minutes:

    vibeview dev-stop

Every command accepts --json for a single line of machine-readable output, which is what a CI step should parse.

Read what the device did, not what you asked for

set-posture reports where the device ended up: the posture it settled in, the hinge angle and the size of the screen now showing. With --angle it also names the lit screen, cover or inner. Treat that as the result, because the device decides which screen to light the way the hardware does. On the way down, the inner screen can stay on until the hinge is almost shut, so --angle 75 can land on either screen depending on where the device was before. Even a preset is a request: coming down from a partly open hinge, partial can settle as closed on the cover screen. A test that needs a known screen should read the reported posture and screen back before it continues, and fold again if they are not what it expects.

rotate reports the new orientation: portrait, landscape_left, landscape_right or portrait_upside_down. On the Duo it also says how the screen’s contents turned. An app that supports the new orientation turns its layout; the Home screen and portrait-only apps turn with the device.

Taps follow the lit screen

This is the part idb #965 is about. After a fold, VibeView’s tap, swipe and the other gestures go to the screen the device is using, cover or inner, with no display to pick. Folding changes the screen, so element references from before are stale; the response carries the new screen, and vibeview ui-tree fetches it again. A device that is still folding refuses a rotate; run it again once the fold has settled.

Hand it to a coding agent

Over MCP, the same controls are tools. Register the server once (Claude Code shown; Cursor, VS Code and others are in Agent Control):

claude mcp add vibeview -- vibeview mcp

The agent then calls list_device_models to find the Duo, dev_start with model: "iPhone Duo" to start on it, set_posture with either posture (closed, partial, open) or angle (0 to 180), and rotate. A prompt as plain as “open the app on the iPhone Duo, unfold it and check the list layout on the inner screen” is enough; you can watch along and take over on the session page at any time.

Put it in a recorded test (beta)

VibeView’s own AI tests can fold the Duo as a step: on the iPhone Duo the test agent gets a set_posture tool for Closed, Partial or Open. AI testing is in beta. A recorded test replays from whatever posture the device is in when the run begins, so either keep the device folded the way the test expects or start the session with a posture, for example ?posture=open on the sandbox URL.

Limits

  • Beta runtime. The Duo runs on the iOS 27.1 beta runtime, and behaviour can change between Apple’s builds.
  • A simulator, not the device. Hinge feel, sensors, camera and performance are not simulated, and the inner screen’s pixel size differs from the hardware’s. Keep a pass on hardware before release.
  • Sessions are metered. A detached session uses streaming minutes until dev-stop, so end it at the end of every CI job.

More on the device itself: the iPhone Duo simulator page.

Try it yourself

Open a live iOS simulator or Android emulator in your browser.

Start free