Test report · head c808dedbf2f23f567bd7bc116047d0ce6c034b5c · base V2 t3code/codex-turn-mapping (not rebased, not merged)
pingdotgg/t3code#12892 (extends #12599). In the shared web/desktop composer:
Option/Alt+Up walks backward through queued messages; Option/Alt+Down walks forward and past the last entry returns to the original draft.thread.editNextQueuedMessage command), and queued image thumbnails are nudged 1px to line up with the text.Native mobile has its own code and is not changed by this PR.
Setup: an isolated worktree with its own .t3 state, vp i, and vp run dev (server on 13838, web on 5798), with no VITE_* origins set. A real Codex provider ran a long sleep turn with four queued messages behind it: a short one, a long multiline one, one with an image attachment, and one more. Every save, cancel, reorder and removal was checked against the server's SQLite state, not just the UI.
Devices: Mac web on macOS 27.0 (T3 Browser panel) · iPhone 17 Pro simulator on iOS 26.5 · T3Code_API_36 emulator on Android 16 (arm64). Both mobile devices were driven through T3's Device panel with AgentDevice.
| Behavior | Web (Mac) | iOS | Android |
|---|---|---|---|
| Option+Up backward; stays on first entry at the boundary | Pass | Not in mobile | Not in mobile |
| Option+Down forward; past last entry restores the draft | Pass | Not in mobile | Not in mobile |
| Unsaved edit blocks switching (typed text, removed attachment, pencil click) | Pass (toast) | Fail: silent loss | Fail: silent loss |
| Save persists and reopening shows it (Enter; ⌘Enter during a turn; "⌘ + Enter always" setting) | Pass | Pass (Update) | Pass (Update) |
| Cancel / Escape discards the edit; saved message unchanged; independent draft restored | Pass | Pass | Pass |
Escape closes @ suggestions and image preview first; held Escape doesn't discard | Pass | n/a | n/a |
| Shift+Enter / Return inserts a newline while editing | Pass | Pass | Pass |
| Reorder and removal persist; navigation follows the current order | Pass | Pass | Pass |
| Queue held after server restart → Resume drains it | Pass | Pass | Pass |
| Image thumbnail aligned with text; long multiline entry truncates cleanly | Pass | Pass | Pass |
| New keybindings listed in Settings → Keybindings | Pass | n/a | n/a |
| iOS hardware-keyboard Option+Up | — | Not tested: AgentDevice can't send modifier keys, and mobile has no handler | — |
Platforms: iOS 26.5 simulator and Android 16 emulator (native app).
Steps: open the queue → edit "Saved with keyboard" → append X → open the image entry without Save or Cancel → return to the first entry.
Expected: a Save/Cancel prompt, or the X kept. Actual: it switches with no prompt and the field shows "Saved with keyboard" again; the X is gone.
Cause: the native queue sheet has no dirty-edit guard. This PR only changes the web/desktop composer, so mobile needs a separate fix.
scripts/mobile-native-client.ts ensure android fails for emulators: it validates the device by serial, but expo run:android --device expects the AVD name.SoLoaderDSONotFoundError: libfbjni.so (fbjni 0.8.1 needs __cxa_init_primary_exception). It runs when built with NDK 28.2.adb reverse. iOS showed "You are offline" until the app was relaunched.<body>, so the next Option+Up/Down does nothing until the composer is clicked. The inline pancake-plating.png reference also stays in the text.Not tested: the Electron desktop shell, Windows/Linux, IME input, and relay/tunnel connections. Web was tested in T3's built-in Chromium panel on macOS.
These are real interactions. Idle waits between actions are cut, and each action plays at recorded speed.
@ suggestions, the second cancels → Option+Down forward to the draft → ⌘Enter saves during an active turn.
Every web/desktop behavior this PR adds works on the Mac. I found no web merge blockers beyond the human review Macroscope already requires. Unsaved-edit loss on native mobile is confirmed on both iOS and Android; it predates this PR and needs its own fix. Not merged.