Resume web CLI sessions on return instead of killing them on inactivity#408
Draft
matt423 wants to merge 2 commits into
Draft
Resume web CLI sessions on return instead of killing them on inactivity#408matt423 wants to merge 2 commits into
matt423 wants to merge 2 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
f311e23 to
11324ca
Compare
A backgrounded terminal was hard-closed after 5 minutes with close code 4002, which handleWebSocketClose treats as non-recoverable: the sessionId was purged and the user had to press Enter to start a brand-new session, losing their shell. Reported as random "disconnects" when a tab is left open in the background. Now the inactivity close preserves the session: the sessionId is kept and the session is transparently resumed (reconnect carries the sessionId) as soon as the tab is foregrounded again. If the server rejects the resume (it reaped the detached session), we fall back to a fresh session rather than dead-ending on the manual prompt. The previously-hardcoded 5-minute timeout is now configurable via a new inactivityTimeoutMs prop, which also makes the pause/resume cycle quick to exercise locally. DX-1379 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed configs are short-lived (the terminal server rejects configs older than a few minutes). A resume-on-return — or any auto-reconnect more than a few minutes into a session — reused the original signed config and was rejected with "Config expired", forcing a noisy retry. Add an optional async refreshCredentials() prop that the component awaits in the open handler, just before sending the auth payload, for both the primary and secondary (split-screen) terminals. Embedders return a fresh signed config; when absent or on error we fall back to the signedConfig/signature props, so behaviour is unchanged for consumers that don't supply it. DX-1379 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
11324ca to
e9404f1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A backgrounded web CLI terminal was hard-closed after 5 minutes (close code
4002), whichhandleWebSocketClosetreats as non-recoverable: thesessionIdwas purged and the user had to press Enter to start a brand-new session, losing their shell. Because visibility isonScreen && document.visibilityState === 'visible', simply switching browser tabs counts as "inactive" — so this surfaced as random "disconnects" when a tab was left open in the background (Ably DX-1379).This PR makes the inactivity close a pause rather than a terminate, and refreshes credentials before reconnect handshakes so resumes don't fail on an expired signed config.
Changes
4002 "inactivity-timeout") now preserves thesessionId. When the tab is foregrounded again the session is transparently resumed (the reconnect carries thesessionId). If the server rejects the resume (it reaped the detached session), we fall back to a fresh session rather than dead-ending on the manual reconnect prompt.inactivityTimeoutMsprop (default unchanged). Also makes the pause/resume cycle quick to exercise locally.refreshCredentials()prop, awaited in the open handler just before sending the auth payload (primary + split-screen). Short-lived signed configs expire (the terminal server rejects configs older than a few minutes), so a resume — or any auto-reconnect more than a few minutes into a session — would otherwise be rejected with "Config expired". Embedders return a fresh config; when the prop is absent or errors, we fall back to the existingsignedConfig/signatureprops, so behaviour is unchanged for consumers that don't supply it.Tests
New
AblyCliTerminal.inactivity.test.tsxdrives the real visibility hook (IntersectionObserver +document.visibilityState) and asserts: pause preserves the session (no purge, closes4002); return resumes carrying thesessionId; a rejected resume falls back to a fresh session; and resume uses freshly-refreshed credentials. Full package suite is green.Notes for reviewers
CLIDrawer), which wiresinactivityTimeoutMsandrefreshCredentials. It depends on a published release of this package exposing the two new props.🤖 Generated with Claude Code