Repository navigation
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds a persisted “Double-tap sends Tab” terminal setting with asynchronous loading, immediate saving, and settings UI state. Introduces double-tap resolution with timing and terminal-handle checks, plus tests for disabled, valid, expired, switched, and reversed-clock taps. A focus-aware hook loads the preference and tracks taps. The session screen uses the hook to send Tab through the accessory-key pathway when the active terminal is tapped twice. 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: fad7d8b4-6e22-453c-a4bf-b72d306b3d6e
📥 Commits
Reviewing files that changed from the base of the PR and between ef985ed and 0df5064381ea35b98304c96f0d96a83795e0e8a1.
📒 Files selected for processing (7)
mobile/app/h/[hostId]/session/[worktreeId].tsxmobile/app/terminal-settings.tsxmobile/src/storage/preferences.test.tsmobile/src/storage/preferences.tsmobile/src/terminal/terminal-double-tap-tab.test.tsmobile/src/terminal/terminal-double-tap-tab.tsmobile/src/terminal/use-terminal-double-tap-tab.ts
6618a37 to
110e55a
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 92995f71-802a-4b78-a19a-e224bc6d116d
📥 Commits
Reviewing files that changed from the base of the PR and between 6618a378a295e4f08869d0cd35b3616c8bf5ff50 and 110e55a.
📒 Files selected for processing (2)
mobile/app/h/[hostId]/session/[worktreeId].tsxmobile/app/terminal-settings.tsx
Greptile SummaryThis PR adds an opt-in "Double-tap sends Tab" mobile terminal setting. Two taps on empty terminal space within 300 ms route a raw
Confidence Score: 5/5Safe to merge — the feature is opt-in (defaults off), isolated to a fixed Tab byte, and every send path is guarded by the existing handle/connection checks in The pure resolver, the hook lifecycle, the preference persistence layer, and the session-screen integration are all covered by focused tests. The Files Needing Attention: No files require special attention.
|
| Filename | Overview |
|---|---|
| mobile/src/terminal/terminal-double-tap-tab.ts | Pure resolver with correct elapsed-time logic, clock-reversal guard (elapsed >= 0), cross-terminal guard, and disabled-state guard; well-tested. |
| mobile/src/terminal/use-terminal-double-tap-tab.ts | Hook wires focus-lifecycle preference reload and activeHandle-change tap reset correctly; useFocusEffect cleanup synchronously clears state before any inflight load can apply. |
| mobile/src/terminal/use-terminal-double-tap-tab-preference.ts | Optimistic-update preference hook with revision-keyed stale-write protection and async recovery; edge cases tested (fast toggle, write failure, interleaved writes). |
| mobile/app/h/[hostId]/session/[worktreeId].tsx | Moves handleAccessoryKeyRef earlier to serve both double-tap and repeat paths; handleTerminalTap restructured cleanly; underlying send guard still validates handle and connection state. |
| mobile/app/terminal-settings.tsx | Adds "Double-tap sends Tab" switch following the existing settings UI pattern; integrates useTerminalDoubleTapTabPreference correctly. |
| mobile/src/storage/preferences.ts | Adds loadTerminalDoubleTapTabEnabled (with try/catch defaulting to false) and saveTerminalDoubleTapTabEnabled following the existing pattern. |
| mobile/src/terminal/terminal-double-tap-tab.test.ts | Covers disabled state, within-window, expired-window, cross-terminal, and clock-reversal cases for the pure resolver. |
| mobile/src/terminal/use-terminal-double-tap-tab.test.ts | Tests the full hook lifecycle: two-tap sequence, terminal-switch reset, blur/refocus with disabled preference reload, and stale-load-after-blur guard. |
| mobile/src/terminal/use-terminal-double-tap-tab-preference.test.ts | Tests fast-toggle precedence over initial load, write-failure recovery, and interleaved-write ordering for the preference hook. |
| mobile/src/storage/preferences.test.ts | Adds regression tests for the new storage key: default-false on null/error and round-trip load/save verification. |
Sequence Diagram
sequenceDiagram
participant User
participant TerminalView
participant handleTerminalTap
participant shouldSendTabForTap
participant resolveTerminalDoubleTapTab
participant lastTapRef
participant handleAccessoryKey
participant sendLiveTerminalInput
User->>TerminalView: First tap on empty space
TerminalView->>handleTerminalTap: "handle="term-1""
handleTerminalTap->>handleTerminalTap: "check handle === activeHandleRef"
handleTerminalTap->>shouldSendTabForTap: call(handle)
shouldSendTabForTap->>resolveTerminalDoubleTapTab: "{enabled, handle, lastTap=null, now}"
resolveTerminalDoubleTapTab-->>shouldSendTabForTap: "{sendTab:false, nextTap:{handle, at:t1}}"
shouldSendTabForTap->>lastTapRef: "store {handle, at:t1}"
shouldSendTabForTap-->>handleTerminalTap: false
Note over handleTerminalTap: focusLiveInput() called, no Tab sent
User->>TerminalView: Second tap within 300ms
TerminalView->>handleTerminalTap: "handle="term-1""
handleTerminalTap->>shouldSendTabForTap: call(handle)
shouldSendTabForTap->>resolveTerminalDoubleTapTab: "{enabled, handle, lastTap:{handle,at:t1}, now=t2}"
resolveTerminalDoubleTapTab-->>shouldSendTabForTap: "{sendTab:true, nextTap:null}"
shouldSendTabForTap->>lastTapRef: clear (null)
shouldSendTabForTap-->>handleTerminalTap: true
handleTerminalTap->>handleAccessoryKey: "{bytes: '\t'}"
handleAccessoryKey->>sendLiveTerminalInput: handle, '\t'
sendLiveTerminalInput->>sendLiveTerminalInput: "guard (rpc, connected, handle===active)"
sendLiveTerminalInput-->>handleAccessoryKey: RPC terminal.send
Reviews (2): Last reviewed commit: "Address mobile double-tap review feedbac..." | Re-trigger Greptile
c1ff0d1 to
85b0188
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 440d29fd-2fb8-4e62-af40-52b5b2dd1a34
📒 Files selected for processing (24)
mobile/app/h/[hostId]/session/[worktreeId].tsxmobile/app/terminal-settings.tsxmobile/src/session/TerminalPaneView.tsxmobile/src/storage/preferences.test.tsmobile/src/storage/preferences.tsmobile/src/terminal/TerminalWebView.tsxmobile/src/terminal/terminal-double-tap-tab.test.tsmobile/src/terminal/terminal-double-tap-tab.tsmobile/src/terminal/terminal-webview-contract.tsmobile/src/terminal/terminal-webview-mouse-click-drag-injected.tsmobile/src/terminal/terminal-webview-mouse-click.test.tsmobile/src/terminal/terminal-webview-notification-dispatch.test.tsmobile/src/terminal/terminal-webview-notification-dispatch.tsmobile/src/terminal/terminal-webview-scroll-routing.test.tsmobile/src/terminal/terminal-webview-tap-dispatch-injected.tsmobile/src/terminal/terminal-webview-tap-routing.test.tsmobile/src/terminal/terminal-webview-url-tap.test.tsmobile/src/terminal/terminal-webview-url-tap.tsmobile/src/terminal/terminal-webview-wheel-scroll-injected.tsmobile/src/terminal/terminal-webview-wheel-scroll.test.tsmobile/src/terminal/use-terminal-double-tap-tab-preference.test.tsmobile/src/terminal/use-terminal-double-tap-tab-preference.tsmobile/src/terminal/use-terminal-double-tap-tab.test.tsmobile/src/terminal/use-terminal-double-tap-tab.ts
🚧 Files skipped from review as they are similar to previous changes (8)
- mobile/src/terminal/terminal-double-tap-tab.test.ts
- mobile/src/terminal/use-terminal-double-tap-tab-preference.ts
- mobile/src/terminal/terminal-double-tap-tab.ts
- mobile/app/terminal-settings.tsx
- mobile/src/terminal/use-terminal-double-tap-tab-preference.test.ts
- mobile/src/storage/preferences.test.ts
- mobile/src/storage/preferences.ts
- mobile/app/h/[hostId]/session/[worktreeId].tsx
Summary
\tthrough the existing accessory-key path, preserving IME flush and active/connected terminal guardsThere is no host-OS branch: the connected shell receives the standard Tab byte on macOS, Linux, and Windows and keeps ownership of completion behavior.
Screenshots
Not included. The UI change is one switch in Terminal Settings.
Testing
cd mobile && node_modules/.bin/tsc.cmd --noEmitcd mobile && node_modules/.bin/oxlint.cmd .oxfmt --checkgit diff --check origin/mainorigin/mainAI Review Report
The final fixed diff was reviewed for gesture routing, terminal identity/lifecycle resets, preference ordering, IME handling, accessory-key transport, and cross-platform host behavior. No remaining P0-P3 actionable findings were found.
Review findings incorporated in this revision:
mailto:as links rather than plain terminal spaceplain tap → excluded gesture → plain tapand unsupported OSC-link double tapsSecurity Audit
Notes
This shortcut is intended for terminal autocomplete from the mobile client. Host-side behavior still follows the connected shell's Tab binding.
ELI5
When enabled, two quick taps on otherwise plain terminal content act like pressing Tab. Taps and gestures that already do something else keep their existing behavior.