Skip to content

feat(mobile): add Shift arrows for Codex queued input and prompt navigation - #408

Merged
Ark0N merged 1 commit into
Ark0N:masterfrom
shenlvkang-collab:feat/codex-shift-arrow-keys
Sep 14, 2026
Merged

Ark0N merged 1 commit into
Ark0N:masterfrom
shenlvkang-collab:feat/codex-shift-arrow-keys

Conversation

@shenlvkang-collab

Copy link
Copy Markdown
Contributor

Phone users cannot invoke Codex's Shift+Left (edit the last queued message) or Shift+Right (prompt stack back) from the keyboard accessory bar. Add ⇧← and ⇧→ beside Tab in both default and extended agent layouts, with accessible labels describing the Codex defaults (verified in Codex 0.154.0 /keymap).

The buttons send the standard modified-arrow sequences through sendNavKey, flushing any locally buffered draft before navigation and handing editing back to PTY echo. Taps refocus the terminal. The shell layout is unchanged.

Validation:

  • Keyboard behavior suite: 65 tests passed, including draft flush order and the two escape sequences.
  • Mobile keyboard runner: 11 relevant tests passed (accessory layout and shell keyboard regressions). Updated the layout assertion to include the new keys and the existing opt-in Read My Mind element.
  • Playwright at 390px: clicked both buttons in both layouts using the real accessory module/styles in an isolated fixture; verified input request payloads and focus retention. This does not claim a physical-device or live Codex round-trip test.
  • Typecheck, lint, frontend syntax, public asset checks, formatting, lockfile check, and production build passed.

Includes a patch changeset and README documentation. AI-assisted; implementation and validation reviewed locally.

@Ark0N

Ark0N commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Thanks for this. The mechanics are right and I checked the three things that usually go wrong here, all clean: \x1b[1;2D/\x1b[1;2C are the standard shift-modified arrows, handleAction's if (action !== 'ctrl') this.clearCtrl() already covers the new actions so the one-shot Ctrl disarms correctly, and the bar is overflow-x: auto with flex-shrink: 0 buttons, so two more keys scroll rather than break the layout. Verifying the bindings against Codex 0.154.0 /keymap rather than assuming them is exactly right.

One thing to change before I take it: gate them on Codex. They are Codex-specific, their own tooltips say so, and right now they ship on both agent layouts, so a claude, pi, grok, omp, deepseek or gemini session gets two keys that do nothing. On the default (non-extended) bar that is two of about eight slots spent on another CLI's binding.

It is not only cosmetic, which is the part I would not have expected either. sendNavKey() does app._echoPassthroughSessions.add(app.activeSessionId), so tapping one of these hands the session to plain PTY echo until Enter or Ctrl+C. On a phone that means a key that does nothing in Claude still turns off local echo for the rest of the prompt, which is the thing that makes typing feel instant there.

The repo already has the pattern, and it is a small change. 🧠 ships in both bar templates and is revealed by an rmm-enabled class on the bar element (keyboard-accessory.js:840, styled at styles.css:11959). It is done that way on purpose: setMode() rebuilds button innerHTML, so per-key state would be wiped on every rebuild, and the class has to live on the container and be re-synced at init and on every applyHeaderVisibilitySettings(). A codex-enabled class following that shape, driven off the active session's mode, is what I am after. Keep the buttons in both templates as you have them.

Happy to merge once that is in.

@Ark0N
Ark0N merged commit 1e5a538 into Ark0N:master Sep 14, 2026
2 checks passed
Ark0N pushed a commit that referenced this pull request Sep 14, 2026
The two keys #408 adds to the mobile keyboard accessory bar send
Shift+Left and Shift+Right, which are Codex bindings (edit the last
queued message, step back through the prompt stack). They shipped on
both agent layouts, so a claude, pi, grok, omp, deepseek or gemini
session got two keys that do nothing. That was not only cosmetic: a tap
goes through sendNavKey(), which adds the session to
_echoPassthroughSessions and hands editing to plain PTY echo until Enter
or Ctrl+C, so on a phone a dead key also switched off the local echo
that makes typing feel instant there.

The reveal now follows the shape the 🧠 key already uses. The buttons
stay in both templates, carry an accessory-btn-codex marker class, and
are display:none in styles.css until the bar element carries
codex-enabled. The class has to live on the bar rather than on the keys
because setMode() rebuilds the buttons' innerHTML on every layout
switch. syncCodexKeys() toggles it from the active session's mode
(the same lookup _isShellSession() uses) and is called at init and from
refreshForActiveSession(), which selectSession() already invokes on
every switch. A session's mode is readonly on the server and fixed at
create, so no other event can change the answer; the welcome screen
(no active session) reads as not codex and hides the keys.

The frontend id-branching guard (test/cli-registry-no-id-branching.test.ts)
scans only src/**/*.ts, so the mode comparison in a public JS file is
in bounds, the same as the existing shell check beside it.

Tests: the new describe block in test/mobile-shell-keyboard.test.ts pins
the marker class in both templates, the CSS pair, the class for a codex
session in both layouts, its absence for claude/shell/pi/omp/deepseek,
the re-sync in both directions on a session switch, the no-session case,
and the init + refresh wiring. All six positive assertions fail without
the source change. README and the changeset now say the keys are
Codex-only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@Ark0N

Ark0N commented Sep 14, 2026

Copy link
Copy Markdown
Owner

Merged, and shipping in 1.29.0: https://github.com/Ark0N/Codeman/releases/tag/codeman@1.29.0

I added the Codex gate myself on master (7c3c5b8f) so this could ride tonight's release: a codex-enabled class on the bar element, the same shape as the Read My Mind key, synced at init and on every session switch (a session's mode is readonly on the server, so switch time is enough). The buttons stay in both templates exactly as you had them. Thanks for checking the bindings against Codex's own /keymap rather than assuming them, that is what made the mechanics a non-question.

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