Skip to content

Simulator devices: T3 parity (Android, 3D/iPhone Duo, SSH hosts, device tabs, power features, phone viewer) - #391

Merged
sambitcreate merged 116 commits into
mainfrom
feature/ios-simulator-upgrades-compare-42da8d
Oct 8, 2026
Merged

sambitcreate merged 116 commits into
mainfrom
feature/ios-simulator-upgrades-compare-42da8d

Conversation

@sambitcreate

@sambitcreate sambitcreate commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

Summary

Brings Aiden's Simulator devices up to T3 Code's Devices panel (T3 a6ec88f7, MIT; ported 1:1 where possible and adapted to Aiden's routes, IPC and design system). It also adds a few capabilities neither app had. Plan: docs/plans/simulator-devices-t3-parity-plan.md.

Workstream What landed
Android emulators platform: "ios" | "android" across contracts. serve-emu SEMU-framed H.264 stream, Android keys plus Back/Home/Recents/Power. Typed adb actions: appearance, text size, Reduce Motion, network, orientation, location, permissions, URL/app. Android SDK and JDK discovery. Paired-Mac relay carries platform. Agent device_* tools support Android. Foldable Fold/Unfold via serve-emu /api/fold.
3D T3's full 3D feel: spring motion with flick coast, rest-view snapping, damped camera framing, log zoom, trackpad pinch, and orbit end on gestureScrollEnd. Hardware-accurate procedural models by device name. iPhone Duo in 3D: hinged two-leaf body, per-display panel streams, touch mapped per leaf, pinch-to-fold with hinge preview, animated fold with hinge re-centring, orientation-following Book/Laptop controls, flip to switch display, Duo snap views. Android 3D fold body. "Save framed screenshot…".
SSH hosts and tool versions SSH device hosts: ssh -L hub and agent tunnels, bootstrap scripts, local-target skip, per-host agent targets, Settings host editor, Test connection. Per-host installed/running/pinned helper versions, consent-respecting update progress, manual Update and Retry, read-only Check versions, locked reclaim, Host diagnostics.
Workspace UX One renameable tab per device (only the visible one streams). Floating device mini-player over chat, auto-shown when the agent opens a device. Quick View docks beside chat on narrow windows. Device rows in the timeline (desktop, iOS, Android).
Power features (iOS and Android) Accessibility-tree overlay, event log (serve-sim feed / logcat), erase (simctl erase / -wipe-data cold boot), clipboard paste (HID Cmd+V / chunked text) and copy (iOS), screen recording (simctl io recordVideo / screenrecord), multi-touch (Option-drag pinch/rotate, Option+Shift pan), screenshot to chat and "Save screenshot…", plus agent device_screenshot saveTo. Controls are gated per platform by deviceFeatureCapabilities.
Phone viewer Native iOS (SwiftUI) and Android (Compose) full-screen simulator viewer over Aiden Remote. Pinned-TLS MJPEG, input over WebSocket, on-demand controls (shake to toggle; Android Back reveals them first), device button above the composer. New simulators:mobile capability behind an owner consent, "Share with Aiden On The Go" (off by default). Aiden Remote contract revision 26. Main claimed 25 for the Bots rework, so this moved to 26 at merge, with the fixture and the desktop, iOS and Android assertions updated together, with fixtures shared by desktop, iOS and Android.

Review and acceptance

  • Two independent review passes. Every confirmed finding is fixed with a behavioral test:
    • SSH stop races
    • phone scope: shutdown refusal and a relay input-tag allowlist that closes with 1008
    • peer device-id rewrite
    • save-folder symlink race
    • AVD-style ids on phones
    • Android in the floating player
    • fresh grants for Duo panel feeds
    • 1006 vs expired grant
    • trusted platform for feature actions
    • mobile touch/lifecycle/retry/frame-memory
  • Live acceptance on this Mac against the real expo-device-hub@0.12.0:
    • iPhone Duo: every fold shape and stance, pinch-to-fold, flip, rotate, touch on the inner display.
    • iPhone 17 Pro and Pro Max in 3D.
    • Power features, including HID Cmd+V paste, a playable recording, and erase on throwaway simulators.
    • Tabs and floating player.
    • A Pixel AVD.
    • Six bugs found and fixed: stale serve-sim helper after shutdown, JAVA_HOME for Android boot, paste key pacing, overlay label clamp, local event-log time, and the procedural Duo camera.

Bundled hardware models

Following the owner's decision on 2026-10-08 to match T3, Aiden bundles T3's device GLBs:

  • iPhone 18 Pro and iPhone 18 Pro Max
  • iPad Pro 13 (M5), with and without the Magic Keyboard
  • iPhone Duo, with its real centimetre hinge rig

These are Apple AR-derived assets with no established redistribution licence. Their provenance and hashes are in renderer/assets/devices/models/sources.json and THIRD_PARTY_NOTICES.md.

How they load:

  • Models load lazily as separate assets, so initial JS is unchanged and the bundle budget passes.
  • A procedural body shows first and is swapped in place once the model loads. On any load or validation failure the procedural body stays.

Coverage:

  • A real-asset test parses every model with three's GLTFLoader.
  • Headless renders of the Pro Max, the iPad with keyboard, and the Duo at 0°, 90° and 180° were checked.

Also fixed from main

Decisions to note

  • Launcher label. Now "Device", since it covers simulators and emulators.
  • Quick View. Shifts or narrows the chat column on narrow windows. This reverses the old "never changes conversation width" rule; docs/chatgpt-desktop-ui-inspiration.md is updated.
  • Android copy-from-device. Disabled with a reason, because API 36 images have no clipboard read.
  • Android recording. Capped at 3 minutes (one screenrecord segment).
  • Phones and Android emulators. Phones list Android emulators as "Open on your Mac to view"; they don't decode H.264 natively yet.
  • Known posture (documented follow-up). While an SSH host is connected, its hub forward is reachable by local processes on loopback, the same as the local hub today.

Tests

  • npm run type-check, npm run type-check:e2e, eslint .: clean.
  • npm run test:devices: 564 pass. npm run test:ci-policy: 56 pass. New test files are registered in test:devices and scripts/ci-test-registry.json.
  • npm test (all lanes, after merging main): core-git 2979 pass, runtime-subagents 2887 pass, renderer-other 2245 pass / 1 load-sensitive failure (below) that passes in isolation.
  • Playwright: all environment-devices-* specs, settings-simulator-ssh-hosts.spec.ts and workspace-panel.spec.ts pass.
  • iOS XCTest (AidenOnTheGo scheme, iPhone 17 Pro simulator): full scheme 666 passed / 0 failed; the simulator-viewer, Phase 0 and remote-client suites pass again after the review fixes.
  • Android :app:testDebugUnitTest: 530 tests, 0 failures.

Flaky and pre-existing failures seen locally and in CI (per AGENTS.md)

  • Android AidenChatProgressUiTest flaked on main too, and is now fixed here.
    • Root cause: Espresso.pressBack() picks a root by focus. Right after a state restore it can pick the activity window while the recreated bottom-sheet dialog holds focus, then time out (RootViewWithoutFocusException).
    • Main runs that failed the same way: 37831916309 and 37722482284.
    • Fix: back is now pressed on the sheet's dialog root. The class passed 10/10 on a headless emulator.
  • Hosted E2E only: floating-player drag test.
    • Root cause: Linux CI runs in a small xvfb window. A phone-shaped player is narrow there, so the test's grab point at handle x+40 landed on a header button, and a press on a button never starts a drag.
    • Reproduced locally at 640×480 and 800×600.
    • Fix: the test now grabs the grip. It passes at 640×480, 800×600 and 1280×1024.
  • tests/e2e/workspace-panel.spec.ts:294 and :328 race on main.
    • Symptom: the "LM Studio (local) added." onboarding toast intercepts the "New browser tab" click, and Sonner keeps a hovered toast open.
    • Reproduced on origin/main (4cb409d5).
    • Fixed here with a waitForToastsToClear fixture: the pointer leaves and the test waits for the toast to close. No timeouts or retries were changed.
  • main/services/coding-tools.test.ts "foreground scans cap work on wide no-match directories and bound output" failed once.
    • Symptom: list_dir returned 5942 entries, expected 10000.
    • This was during a full local run while live simulator acceptance was saturating the machine. The test passes in isolation and on the other full runs.
    • This PR doesn't touch coding-tools. It looks like a time-budget sensitivity worth a follow-up.

🤖 Generated with Claude Code

sambitcreate and others added 30 commits October 8, 2026 13:48
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… actions

Adds the main-process side of the simulator power features. Erase, clipboard
transfer, and screen recording are typed simctl argv builders in
device-actions.ts with a platform discriminator; a supervised recorder stops
with SIGINT, caps at ten minutes, and is discarded on chat delete, quit, or
device shutdown. New devices:* IPC channels parse targets fail-closed and
save only through the user's dialog.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The agent's device_screenshot can also write the PNG to a path inside the
chat's workspace or the Downloads folder. Paths are checked lexically and
again through symlinks, never follow a final link, and are validated before
the capture. A screenshot that writes a file asks first under ask permission.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DevicePlatform is now ios | android. Device ids accept AVD names and adb
serials but must start alphanumeric so none can read as a flag. Hosts report
per-platform availability, Android gains setOrientation and the network
switch, and deviceActionSupported says what each platform can run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…form

The local host discovers the SDK from ANDROID_HOME, Android Studio's default,
or the adb on PATH, reports a clear reason when a tool is missing, and puts
platform-tools and emulator on the hub's and host commands' PATH. The hub now
starts when iOS or Android can run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Appearance, text size, Reduce Motion, network, orientation through the
emulator's accelerometer, location, eight permission groups, open URL,
launch and quit. Every step is an adb argv; arguments after adb shell are
quoted for the device's shell, which re-parses them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…service

Emulators come from the hub's /api/devices plus emulator -list-avds, beside
simctl's simulators. Booting an AVD goes through the hub and the session
follows the returned serial; shutdown, screenshots, settings and actions
route by platform. Boot failures are classified as in T3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The proxy allowlist adds T3's serve-emu routes and the video and gesture
socket. Device-scoped serve-emu routes need one valid ?device=, each mutable
route takes only its own method, and routes report read or operate scope
(fold GET reads, POST operates). The paired-Mac relay carries platform,
relays the Android stream and fold, and keeps stream tuning local.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
device_list reports each device's platform and the host's platform
availability; device_open takes a platform and pins agent-device with
--platform android --serial. The quick start gains Android lines, and the
always-on guidance names emulators while still allowing adb.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Port of T3's Android stream path: one WebSocket carries SEMU-framed H.264
Annex-B down and JSON gestures up. The decoder configures from the keyframe's
SPS, decodes with the packet pts, asks for keyframes with reset-video, and
rebuilds on serve-emu's video-session restart without dropping input. Keys
map to text, keycodes, or Back; buttons to home, back, recents, power.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Shared, fail-closed shapes for SSH device hosts (validated drafts, unique
ids, dash-led targets refused), per-host helper versions, and connection
check results. Adapted from T3 Code's device contracts (MIT).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ssh-device-script: the Node bootstrap piped to SSH hosts (probe, start,
  agent-start, stop-agent, stop) under a per-install owner id. Starts never
  install unless the user approved it; missing tools exit with a marker.
- ssh-device-host: ssh -L forwarding of the hub and agent-device daemon,
  ServerAlive keepalives, bounded reconnect backoff, no health polling.
- local-ssh-target: skip targets that resolve to this Mac (ssh -G).
- ssh-host-store: hosts and per-host install approval in userData.
- device-tool-maintenance: one locked prune/reclaim pass for this Mac and
  SSH hosts that keeps versions running helpers use; replaces the unlocked
  pruneOldToolVersions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t tools

SSH hosts list after This Mac and paired Macs and are contacted only from
Refresh, Connect, Open, Test connection, Install, Update, or Check versions.
Streams reach them through the forwarded loopback hub and the token proxy.
device_list/device_open see connected SSH hosts via per-host agent-device
configs; agents never connect or install on a host. Outdated local helpers
update on an explicit Start when the user already approved them, then the
old versions are reclaimed under the maintenance lock.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…helpers

serve-sim's helper accepts two contacts in one 0x05 packet, so the stream
client gains sendMultiTouch with the same rotation remap as single touches.
device-multitouch.ts holds Simulator.app-style Option and Option+Shift
gestures plus trackpad pinch as pure geometry. device-ax.ts ports T3's tree
flattening and maps frames into the displayed stream as it rotates;
device-event-log.ts reads the hub's event log over SSE into a bounded buffer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
device_open now reveals the exact host and device it opened, so the
renderer can float that device over the chat or select its tab. The
payload stays { chatId } when no device is named.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
device_list, device_open, device_screenshot and device_close get
readable labels in the persisted timeline (never the device ids) and
matching verbs in the desktop, iOS and Android activity rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…er chat

The Environment panel shows one tab per device session in the chat,
named after the device and renameable per chat (double-click, F2, or
the context menu). + -> Device opens the picker, which adds a tab.
Closing a tab ends that viewer session without shutting the simulator
down, and closed tabs never come back from a refresh. Only the selected
tab streams.

A device can float over the chat in a draggable, resizable player that
snaps to edges and corners, keeps its size and position for the window,
stays inside the chat area, and docks with Escape. An agent's
device_open floats the device unless Settings -> Simulator -> Auto-show
floating device is off, in which case its tab comes forward.

On narrower windows Quick View docks beside the chat: the column moves
left only as far as the card needs and narrows only at the left edge
(adapted from T3 Code, MIT).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contract revision 25 adds the phone-only simulators:mobile grant behind the
mobile-simulators-v1 feature. Phones negotiate it after pairing; desktops keep
simulators:control. A new owner consent in Settings > Simulator, Share with
Aiden On The Go (off by default), gates the phone audience separately from
Share with paired Macs, and turning it off closes only phone relays.

- Phones may list, open (iOS only), shut down, stream MJPEG, read the screen
  config and health, and drive the helper input socket. Settings, device
  actions, screenshots, H.264, the accessibility tree, the event log and the
  device-list socket stay desktop-only (403 capability_denied).
- GET /simulators?chatId= (chat:read plus a visible chat) adds chatDeviceIds
  and never starts the hub; phones also receive toolVersions.
- The shared fixture gains a mobileSimulators section (listing, input and
  screen-config vectors, MJPEG samples) that a desktop test checks against
  the real stream encoder.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Aiden On The Go for Android negotiates simulators:mobile when the Mac
advertises mobile-simulators-v1 and shows a device button above the composer
when the chat has simulators (GET /simulators?chatId= on open and resume,
never polled). The viewer is an immersive full-screen dialog: MJPEG over the
pinned OkHttp client, decoded off the main thread with latest-frame-wins,
input over an OkHttp WebSocket with the shared HID encoders, on-demand
controls toggled by shake with a haptic, and Back revealing controls before
it exits. Android emulators are listed as Open on your Mac to view.

Adapted from t3code apps/mobile/src/features/devices (MIT).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds the revision-25 phone simulator section and simulators:mobile grant to
the Aiden Remote API doc, a mobile viewer section to docs/devices.md, project
memory, and the T3 Code MIT notice in both mobile apps' bundled notices.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ick View

The stream spec now opens a device into its own tab, renames it, floats
it (touch, drag-to-corner snap, Escape and Dock), closes the tab and
checks it stays closed until the device is opened again under its saved
name. The agent spec expects device_open to float the device. The
workspace spec checks Quick View docks beside the chat on a narrower
window and floats over it when there is no room.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Port of T3's fold controls. A framework-free controller reads serve-emu's
/api/fold through the proxy, re-reads when the screen size changes, retries
a failed read every 3 s, and times a command out after 12 s with
"Fold command timed out." useAndroidFold exposes the posture and hinge
angle (0 to 180) for the flat controls and the 3D frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The list groups devices by host and platform and says why a platform is
unavailable, such as a missing Android SDK. An Android viewer gets Back,
Home, Recents and Power plus an orientation menu, sends key text, shows the
fold controls in the flat view, and keeps the last frame with "Waiting for
device video…" while serve-emu restarts its encoder. The tools drawer hides
what an emulator cannot do.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The rail gains a joined screenshot control (to chat, or save to a file) and
a screen-recording button with a live elapsed indicator. The tools drawer
gains the accessibility overlay switch, clipboard transfer, a filterable
event log, and erase with a destructive confirmation and a boot-again offer.
The flat screen draws element frames with hover labels, and takes
Option-drag pinch/rotate, Option+Shift-drag pan, trackpad pinch, and Cmd+V.
Each feature is its own component, mounted with small edits.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s UI

- Settings → Simulator gains an SSH hosts group: add, edit, remove, Test
  connection, Connect/Retry, and consented Install for the hub and agent
  tools, following the settings design system.
- Helper tools show running, installed, and pinned versions, an Update
  button under the matching permission, and a read-only Check versions.
- Per-host update progress with Retry, shared by Settings, the Simulator
  tab before its hub is ready, and a Host diagnostics section in the
  Device tools drawer.
- The Simulator tab groups SSH hosts after This Mac and paired Macs, with
  Connect, and Start is now the explicit action that may update helpers.

Adapted from T3 Code's DeviceHostsSettings, DeviceHostEditor,
DeviceToolVersions, and DeviceHostUpdates (MIT).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…og, erase

The fake hub answers the accessibility tree and seeds the event log. A new
spec drives the real viewer: saves a screenshot through a main-answered save
dialog, checks Option-drag sends one mirrored multi-touch packet, toggles the
element-frame overlay with hover labels, filters the event log, and confirms
erase runs shutdown then erase only after the destructive confirmation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sambitcreate and others added 10 commits October 8, 2026 16:47
…o the shipping allowlists

The shipping-target policy test pins every Swift source in the app and test
build phases and every bundled third-party notice. Register the Aiden On The Go
simulator viewer sources (contract, MJPEG parser, stream, viewer and model),
its XCTest file, and the T3 Code license notice, and require NOTICE.txt to
attribute the adapted viewer logic.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ptor

writeDeviceSaveFile validated each folder by path, then opened the final
path with O_NOFOLLOW|O_TRUNC. O_NOFOLLOW guards only the last component,
so a checked parent swapped for a link to an outside folder just before
the open let the truncating write land outside the workspace or
Downloads.

The native aiden-worktree-file-io helper gains a save operation: it
reopens the root by its captured device and inode, opens each folder
beneath the previous descriptor with O_NOFOLLOW, writes an O_EXCL
temporary in the held parent and renameats it over the leaf through that
descriptor. A swapped ancestor makes it refuse, and an existing file is
replaced as an entry, so a hard link to an outside file is no longer
written through. The Node walk stays for clear errors. pretest:devices
builds the helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…land where shown

serve-sim streams the raw portrait framebuffer. The viewer aspect-fitted that
frame unturned while the touch encoder already applied the inverse orientation
remap, so a landscape or upside-down simulator was drawn sideways and taps
landed somewhere else.

AidenSimulatorDisplayRotation is now the one predicate for both: the viewer
draws the frame turned by it (rotationEffect about the shown rect's centre),
aspect-fits the turned size, and normalizes touches against that rect before
rawPoint maps them back into the raw framebuffer. Tests cover the shown rect
for every orientation, a round trip that draws raw pixels with an independent
affine rotation and taps them, and the shared fixture's touch vectors tapped
on the shown frame.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…aps land where shown

Same finding as iOS: SimulatorFrame drew the raw portrait JPEG aspect-fit and
unturned while AidenSimulatorInput.mapTouch applied the inverse orientation
remap. AidenSimulatorDisplayRotation now drives both. The frame is drawn turned
about the shown rect's centre (drawBehind + rotate), the shown rect is the
aspect-fit of the turned size, and touches normalize against it before
mapTouch. The last rotation stays with the last frame through a reload. The
decoder subsamples against the turned size so a landscape frame is never
sampled below its drawn size.

Unit tests cover the shown rect per orientation, a tap round trip against an
independent rotation, the shared fixture's touch vectors tapped on the shown
frame, and turned subsampling. docs/devices.md and the mobile viewer memory
record the shared display-space contract.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…install

updateTool checked consent before joining the granting queue, and the
queued callback then installed unconditionally, so an update queued
behind another one still installed after agent access or streaming was
turned off. The SSH agent update likewise installed after an
agent-access revoke that landed while the host was connecting.

Updates now snapshot the streaming and new agent revoke counters when
the user acts, and requireInstallConsent rechecks them immediately
before each install: local updates (including the agent update inside
Start) and the SSH agent install. A streaming revoke that races the SSH
approval save also drops that host's re-added approval.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t installs

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…f-window

Hosted CI windows do not deliver a pointer drag to x-4000, so the player never
moved. Drop it just inside the chat's top-left corner, as a person would.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…views

serve-sim streams the raw framebuffer, so a simulator rotated to landscape can
keep sending portrait frames. The touch remap already assumed a turned display;
draw the frame turned too (ported from T3's DeviceStreamView) in the flat viewer
and the floating player, so taps land where they show.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-upgrades-compare-42da8d

# Conflicts:
#	android/app/src/main/java/sbtbiswas/AidenOnTheGo/features/chat/AidenChatDetailScreen.kt

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

The new desktop rotation path misplaces taps in width-constrained flat views and desynchronizes accessibility highlights. These two behavioral issues should be addressed before merging.

Reviewed changes: Reviewed the changes since the previous Pullfrog review at 3b333ec, including the review fixes and the additional desktop orientation correction.

  • Hardened screenshot saves: Replaced pathname-based truncation with a native held-parent temporary-file and rename operation, with parent-swap and hard-link coverage.
  • Invalidated queued install approvals: Added streaming/agent revocation epochs and service-level checks before queued local and SSH install requests.
  • Corrected native orientation: Shared the display-rotation predicate with touch encoding on iOS and Android, fitted rotated frame dimensions, and adjusted Android subsampling.
  • Rotated desktop media: Turned flat-view and floating-player media and updated their displayed aspect ratios.
  • Updated integration checks: Reserved floating-screen typing, updated iOS shipping/notice allowlists and the browser floating-frame test, and changed the drag test to drop inside the chat window.

Validation: TypeScript checking, 52 focused desktop tests, 14 iOS shipping checks, and 30 focused Android viewer/stream tests passed. A browser probe using production CSS and geometry helpers reproduced both inline findings. The full device suite on Linux reported 564 passes, 5 failures, and 3 skips; all five failures encounter the new writer's Saving screenshots to a file needs macOS. refusal, so native screenshot-save execution still requires macOS verification. iOS XCTest and macOS Electron acceptance were not run here.

Scope: Re-read the complete incremental delta and affected full-diff regions/callers, reusing the prior full review for unchanged code rather than repeating it.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using gpt-6.1-sol | 𝕏

Comment thread renderer/components/device-viewer.tsx Outdated
Comment thread renderer/components/device-viewer.tsx
sambitcreate and others added 2 commits October 8, 2026 17:29
…he overlay with it

A width-bound flat screen kept its full height, so a turned frame letterboxed
inside it while taps normalized against the whole box. Size the screen box to
the largest displayed-aspect box that fits its stage (container-query units),
in the viewer and the floating player, so touches, multi-touch and the overlay
all map against the image. The accessibility overlay now maps its tree into
the displayed (turned) screen instead of the raw framebuffer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The test:devices conflict is resolved as a union, keeping the branch's
pretest:devices step and every suite from both sides.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes: Reviewed the display-geometry fixes since the previous Pullfrog review at 94b2e386, excluding changes inherited from the merge of main.

  • Fitted flat screens: Sized the full viewer and floating player's input surfaces to the largest displayed-aspect rectangle that fits their parent, keeping rotated media and touch bounds aligned.
  • Aligned accessibility overlays: Passed displayed screen geometry to the overlay so interface-space rectangles remain aligned and raw portrait trees map into landscape display space.
  • Extended geometry checks: Added focused tests for width/height constraints and displayed accessibility screen configuration.

Validation: npm run type-check and all 30 focused display, accessibility, multi-touch, player-layout, and player-render tests passed. An independent Chromium probe using production helpers and compiled production CSS passed 32 viewer/player layout cases across four sizes and all four orientations, plus accessibility hit tests for interface-space trees, raw portrait trees, and already-rotated iOS/Android frames. macOS Electron acceptance and native suites were not rerun on this Linux runner.

Scope: Read the complete incremental and head-commit diffs, affected full-diff regions, and relevant callers; reused prior full-review coverage for unchanged implementation rather than repeating it.

Pullfrog  | View workflow run | Using gpt-6.1-sol | 𝕏

Adds T3 Code's five device GLBs and their sources.json, unchanged, under
renderer/assets/devices/models/ (Apple Inc. AR assets; no redistribution
licence is established; owner decision 2026-10-08). Vite emits each as a
separate asset fetched only when a matching device is shown in 3D, so the
main window's initial JavaScript is unchanged.

bundled-models.test.ts parses every model with three's real GLTFLoader:
the phone and iPad bodies meet the normalized display contract, the Magic
Keyboard has finite bounds, and the Duo exposes its hinge groups and three
displays and folds the inner halves face to face.

A phone or iPad GLB body now gets T3's phone lighting without the room
environment, whose reflections turned its Dynamic Island and bezel grey;
procedural bodies keep their reflections.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes: Reviewed the flat-view sizing and accessibility-coordinate fixes in 3580dfd, following the previous Pullfrog review at 94b2e386.

  • Fitted flat screens: Sized the viewer and floating player's input surface to the largest displayed-aspect rectangle that fits its parent, keeping rotated media and pointer bounds aligned.
  • Aligned accessibility overlays: Passed displayed screen dimensions and orientation into accessibility mapping so highlights and hover hit tests follow the turned image.
  • Extended geometry checks: Added width-bound/height-bound sizing cases and displayed-screen mapping tests.

Validation: All 53 focused geometry, accessibility, input, layout, and renderer tests passed, as did npm run type-check. A Chromium probe using production CSS and geometry functions passed 12 combinations of stage size and orientation, checking matching media/input bounds, containment, and off-center accessibility hit testing. This was a focused browser probe, not macOS Electron acceptance.

Scope: Read the complete incremental delta, the four-file commit diff, affected authoritative full-diff regions, and related callers; reused the earlier full review for unchanged code rather than repeating the entire 236-file review. Previous Pullfrog threads are already resolved. Hosted checks on this exact head had not completed when checked; this review does not establish CI readiness.

Pullfrog  | View workflow run | Using gpt-6.1-sol | 𝕏

sambitcreate and others added 2 commits October 8, 2026 17:47
…-upgrades-compare-42da8d

Main claimed Aiden Remote contract revision 25 for the Bots rework (#377), so
the phone simulator viewer moves to revision 26: the constant, fixture,
desktop/iOS/Android revision assertions, the mobile fixture gate, and the
simulator-scoped docs and OpenAPI text. Also fix main's chat-pane, which
still read the removed bot query after #377 and #373 crossed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…Magic Keyboard, iPhone Duo)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sambitcreate
sambitcreate enabled auto-merge October 8, 2026 21:49

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes: Reviewed the bundled-model and merge-integration delta since the previous Pullfrog review at 3580dfdb.

  • Added bundled hardware models for the iPhone 18 Pro/Pro Max, iPad Pro 13-inch M5, Magic Keyboard, and iPhone Duo, with provenance and the owner-accepted licensing decision documented.
  • Added asynchronous model loading with cancellation, resource cleanup, validation, and procedural fallbacks; adjusted phone/iPad lighting and Duo scale-aware replacement.
  • Added Magic Keyboard controls that attach the matching accessory and preserve its landscape resting orientation.
  • Updated merge integration to reserve remote contract revision 26 across the shared fixture and client assertions, register model tests, and remove the stale Bot query reference in chat-pane.tsx.

Validation: All 77 focused 3D/model tests, 157 protocol/renderer integration tests, 61 Android contract/viewer tests, and 13 iOS shipping checks passed. TypeScript checking, the production renderer build, and the bundle budget passed. An isolated Electron file:// probe loaded all five real GLBs, decoded embedded textures, rendered the device bodies, and passed 12 off-center phone/iPad input checks across all four orientations.

Scope: Read the complete incremental delta, affected authoritative full-diff regions, and related consumers; reused prior full-review coverage for unchanged implementation rather than repeating the entire PR. iOS XCTest and macOS simulator acceptance were not run here. Hosted CI on this exact head was still incomplete, so this review does not establish merge readiness.

Pullfrog  | View workflow run | Using gpt-6.1-sol | 𝕏

sambitcreate and others added 2 commits October 8, 2026 18:20
#373 made approval tool labels sentence case after #377's Bot chat test was
written, so main's renderer-other lane fails on 'share image'.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fore dragging

On hosted runners the player never moved: page.mouse does not check what is
on top, and the onboarding toast can cover the handle. Wait for toasts to
clear and hover the handle (an actionability check) before the drag.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes: Reviewed the floating-player E2E synchronization fix in 8dc3757, following the test-label-only acknowledgement at b1a61d24 and the previous substantive review at 3da48fbb.

  • Added toast synchronization before dragging, using the existing helper to move the pointer away from hover-paused notifications and wait for their removal.
  • Added handle actionability checking before measuring and dragging the player, preserving the existing snap and position-persistence assertions without increasing timeouts or retries.
  • Corrected the Bot approval expectation in the previously acknowledged b1a61d24 to match the existing sentence-case tool label.

Validation: E2E TypeScript checking and lint for the changed spec passed; Playwright collected the updated stream test successfully. The actual Electron test requires macOS and was not run on this Linux runner, so elimination of the hosted flake remains unverified here.

Scope: Read the complete incremental and commit diffs, the affected authoritative full-diff regions, fixture helper, complete spec, and player pointer handlers. Reused prior full-review coverage for unchanged implementation rather than repeating the entire PR for this test-only change. All earlier Pullfrog threads remain resolved; repository sources are unchanged. This review does not establish hosted CI readiness.

Pullfrog  | View workflow run | Using gpt-6.1-sol | 𝕏

sambitcreate and others added 2 commits October 8, 2026 19:04
Hosted Linux CI runs in a small xvfb window, where a phone-shaped player is
narrow and its header buttons cover the handle at x+40, so the press landed on
a button and never started a drag. Reproduced locally at 640x480 and 800x600;
grabbing the grip passes at 640x480, 800x600 and 1280x1024.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Espresso.pressBack() picks a root by focus; right after a state restore it can
pick the activity window while the recreated sheet window holds focus, then
time out with RootViewWithoutFocusException. This flaked on main and blocked
the required Android job here. Target the sheet's dialog root explicitly.
AidenChatProgressUiTest: 10/10 on a headless emulator.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes: Reviewed the two test-behavior fixes since the previous Pullfrog review at 8dc3757.

  • Changed the floating-player drag target from header offset 40 to 10, placing the initial press on the grip rather than a header button while preserving snap and position-persistence assertions.
  • Targeted Android Back at the sheet dialog using an explicit Espresso dialog-root matcher, preserving real Back-key injection and the nested navigation, restoration, and dismissal assertions.

Validation: E2E TypeScript checking, lint for the changed spec, and focused Playwright collection passed; all 10 focused mini-player renderer/layout tests passed. Android instrumentation-test compilation completed successfully with cached tasks using --offline --no-daemon; two preceding synchronous attempts hit Tool 'shell' timed out after 120000ms. The actual Android instrumentation tests and macOS Electron flow were not run here, so runtime elimination of the flakes remains unverified locally.

Scope: Read the complete incremental and both commit diffs, affected authoritative full-diff regions, both complete test files, and the production drag/back handlers. Reused prior full-review coverage for unchanged implementation rather than repeating the entire PR for two isolated test fixes. Earlier Pullfrog threads are already resolved. CI on this exact head still had Android, iOS, Linux, and Electron E2E checks in progress when inspected; this review does not establish merge readiness.

Pullfrog  | View workflow run | Using gpt-6.1-sol | 𝕏

@sambitcreate
sambitcreate merged commit 203a8f2 into main Oct 8, 2026
27 checks passed
@sambitcreate
sambitcreate deleted the feature/ios-simulator-upgrades-compare-42da8d branch October 8, 2026 23:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants