Skip to content

Fix terminal IME input and mobile session persistence - #38

Closed
goxofy wants to merge 9 commits into
Termix-SSH:dev-1.5.0from
goxofy:worktree-fix-ime-terminal-input
Closed

Fix terminal IME input and mobile session persistence#38
goxofy wants to merge 9 commits into
Termix-SSH:dev-1.5.0from
goxofy:worktree-fix-ime-terminal-input

Conversation

@goxofy

@goxofy goxofy commented Aug 3, 2026

Copy link
Copy Markdown

Summary

This PR fixes two cross-platform mobile issues:

  1. Terminal input now handles IME composition correctly on iOS and Android.
  2. Server configuration and authenticated sessions now persist reliably across app restarts.

Terminal IME handling

The previous hidden React Native TextInput forwarded intermediate composition updates to the terminal. With Chinese Pinyin and similar IMEs, this caused composing Latin characters to appear remotely—sometimes twice—before the selected candidate was sent as well.

This PR replaces the heuristic input handling with a local Expo native view module:

  • iOS: uses markedTextRange to distinguish marked/composing text from final committed text.
  • Android: uses InputConnection composition APIs such as setComposingText, setComposingRegion, finishComposingText, and commitText.
  • Sends only final committed text to the SSH terminal.
  • Keeps Backspace, Enter, arrows, Tab, Delete, Home/End, Page Up/Down, and function keys on a unified terminal-key mapping path.
  • Avoids duplicate special-key delivery from overlapping native input sources.
  • Adds the iOS podspec and Android Gradle library setup required for Expo autolinking.

The implementation is composition-aware rather than language-specific, so it also applies to Japanese conversion, Korean composition, and compatible third-party keyboards.

Mobile session persistence

The mobile startup flow could appear to forget both the configured server and the authenticated session. It restored local state only after network-dependent checks, and any /users/me failure could delete the stored JWT—even for temporary network, TLS, proxy, or server errors.

This PR updates the flow to:

  • Restore the configured server before running network-dependent version/session checks.
  • Migrate the legacy stored server format when present.
  • Persist and verify the final JWT before treating password, TOTP, or OIDC login as successful.
  • Recover a reusable JWT from an HttpOnly cookie session through the existing /users/me/token endpoint when necessary.
  • Preserve the stored session during offline starts and transient server/proxy failures.
  • Clear the JWT only after a confirmed 401 Unauthorized response.
  • Keep the configured server after token expiry so the UI offers Sign in rather than Add server.
  • Clear cached per-user identity when signing out, changing servers, or receiving a confirmed 401.
  • Avoid storing usernames or plaintext passwords.

Build workflow

  • Uses the GitHub-hosted macos-15 runner for the unsigned iOS/iPadOS workflow so forks without access to the upstream Blacksmith runner can execute it.

Verification

  • npm run lint — completed with 0 errors (existing repository warnings remain).
  • npx expo export --platform all — iOS, Android, and web bundles generated successfully.
  • npx expo-modules-autolinking resolve --platform android — resolves terminal-ime-input and TerminalImeInputModule.
  • npx expo-modules-autolinking verify --platform android — passed.
  • :terminal-ime-input:compileReleaseKotlin — passed.
  • app:assembleRelease for arm64-v8a — passed.
  • Unsigned iOS IPA workflow — completed successfully.
  • Manual terminal IME testing on iOS and Android confirmed that composition text no longer leaks or duplicates and final candidates are committed once.

npx tsc --noEmit still reports pre-existing errors in WarpgateDialog.tsx and TunnelManager.tsx; no new TypeScript errors were reported in the files changed by this PR.

🤖 Generated with Claude Code

Tink and others added 9 commits August 3, 2026 10:02
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@ZacharyZcR

Copy link
Copy Markdown
Member

The target branch has been updated to dev-1.5.0. The session-persistence portion is now superseded by merged PR #40, and the iOS Backspace regression is covered by merged PR #44. Please split this down to the native composition-aware IME module only and drop the unrelated auth/session and CI workflow changes before it can be reviewed safely.

@ZacharyZcR

Copy link
Copy Markdown
Member

Thank you for the native IME work. It has been extracted and rebased onto dev-1.5.0 in #47, with the original implementation commits and authorship preserved. The replacement intentionally excludes the now-superseded session-persistence changes and the unrelated CI workflow edit.

@ZacharyZcR ZacharyZcR closed this Aug 12, 2026
@goxofy
goxofy deleted the worktree-fix-ime-terminal-input branch August 13, 2026 18:07
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