Repository navigation
fix(mobile): retry session capability probe so tab-row actions survive relay cutover - #9794
Conversation
…e relay cutover The session screen learned host capabilities (quick commands, browser screencast, agent history, query-reply input) from a single status.get fired when the screen connected. Over relay, a relay-to-direct transport cutover rejects every in-flight request while connState stays 'connected', and a request timeout does the same — so one transient failure latched the capability flags false (or left them null on an ok:false reply) and the quick-commands tab-row button stayed hidden until the screen was remounted. Replace the one-shot probe with startRuntimeCapabilityProbe: retry promptly after a cutover (the replacement transport is already authenticated) and with capped exponential backoff on other failures, until a probe lands or the effect is cleaned up. Also export the cutover-error predicate from stable-logical-rpc-client and reuse it in worktree-create-capability instead of a local copy.
|
Warning Review limit reached
Next review available in: 14 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughAdds a reusable runtime capability probe that retries failed 🚥 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.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
mobile/app/h/[hostId]/session/[worktreeId].tsx (1)
2318-2333: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick winReset every capability before probing a swapped client.
Only quick-command state is cleared here. A connected client swap can leave browser/agent actions enabled from the prior host, and leave
hostQueryReplyInputSupportedReftrue even when the replacement host lacks the capability—allowing query replies to be forwarded as normal terminal input. Reset those values before starting the probe.Suggested fix
// Why: a client swap can keep the route connected while moving to an older // host; clear the prior capability before exposing host-specific actions. + setBrowserScreencastSupported(null) + setAgentSessionHistorySupported(null) setQuickCommandsSupported(null) setShowQuickCommands(false) + hostQueryReplyInputSupportedRef.current = false // Why: the probe retries — a relay→direct cutover or request timeout rejects
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: bd44ee30-47a5-4230-8efd-a5b1db8d77cb
📒 Files selected for processing (5)
mobile/app/h/[hostId]/session/[worktreeId].tsxmobile/src/tasks/worktree-create-capability.tsmobile/src/transport/runtime-capability-probe.test.tsmobile/src/transport/runtime-capability-probe.tsmobile/src/transport/stable-logical-rpc-client.ts
…gration (#9798) Opening the Quick Commands sheet right after connecting over relay races the relay->direct cutover, which rejects the in-flight one-shot settings.getTerminalQuickCommands with LogicalClientCutoverError while connState stays 'connected'. The sheet then strands on "RPC interrupted by connection migration" with an empty list until closed and reopened. The read is side-effect-free, so replay it on cutover (capped at 5, cancelled if the sheet closes or the client is replaced). Same failure class and pattern as #9794 (capability probe) and #9796 (terminal create).
…e relay cutover (stablyai#9794) * fix(mobile): retry session capability probe so tab-row actions survive relay cutover The session screen learned host capabilities (quick commands, browser screencast, agent history, query-reply input) from a single status.get fired when the screen connected. Over relay, a relay-to-direct transport cutover rejects every in-flight request while connState stays 'connected', and a request timeout does the same — so one transient failure latched the capability flags false (or left them null on an ok:false reply) and the quick-commands tab-row button stayed hidden until the screen was remounted. Replace the one-shot probe with startRuntimeCapabilityProbe: retry promptly after a cutover (the replacement transport is already authenticated) and with capped exponential backoff on other failures, until a probe lands or the effect is cleaned up. Also export the cutover-error predicate from stable-logical-rpc-client and reuse it in worktree-create-capability instead of a local copy. * fix(mobile): reset runtime gates before capability reprobe
…gration (stablyai#9798) Opening the Quick Commands sheet right after connecting over relay races the relay->direct cutover, which rejects the in-flight one-shot settings.getTerminalQuickCommands with LogicalClientCutoverError while connState stays 'connected'. The sheet then strands on "RPC interrupted by connection migration" with an empty list until closed and reopened. The read is side-effect-free, so replay it on cutover (capped at 5, cancelled if the sheet closes or the client is replaced). Same failure class and pattern as stablyai#9794 (capability probe) and stablyai#9796 (terminal create).
Problem
On mobile over relay, the quick-commands button in the session tab row sometimes never appeared; leaving the session and re-entering brought it back.
The session screen learns host capabilities (quick commands, browser screencast, agent session history, terminal query-reply input) from a single
status.getfired when the screen connects. Two transient failure modes reject that probe whileconnStatestays'connected', so the effect never re-runs:migrateToon the stable logical client rejects every in-flight request withLogicalClientCutoverError— but the published connection state goes connected→connected, so no re-probe is triggered.The old
.catchlatched all four capability flagsfalse(and anok:falsereply left themnullforever), permanently hiding the quick-commands button until the screen remounted — exactly the observed one-time disappearance that self-healed on re-entry.Fix
mobile/src/transport/runtime-capability-probe.ts:startRuntimeCapabilityProberetries until a probe lands — promptly (250ms) after a cutover, since the replacement transport is already authenticated, and with capped exponential backoff (1s → 15s) on other failures, includingok:falsereplies which previously wedged silently. Cancellation via the effect cleanup stops the loop;connStateleaving'connected'still resets the flags as before.isLogicalClientCutoverErrorfromstable-logical-rpc-client.tsand reuse it inworktree-create-capability.tsinstead of its local copy.This also heals the other three capability gates fed by the same probe (browser screencast, agent history, query-reply input forwarding).
Verification
runtime-capability-probe.test.ts: first-try success, prompt cutover retry, backoff + recovery,ok:falseretry, backoff cap, cancellation stops retries, and post-cancel results are dropped.tsc --noEmit,oxlint,oxfmt --checkclean.