fix: session stabilization, dedup, and code audit refactor#5
Merged
Conversation
TDD: tests written first, then implementation. SessionRegistry decouples session lifecycle from WebSocket connection lifecycle — sessions survive brief disconnects via detach/reattach with a configurable TTL. Made-with: Cursor
WS disconnect now detaches (not aborts) the session. The SDK query keeps running server-side. On reconnect, the frontend sends a reattach message with the previous clientId. If the session is still alive, the new WS is swapped in and streaming resumes. Detached sessions auto-abort after 2 minutes if no reattach arrives. Made-with: Cursor
getSessions() now deduplicates by session ID (keeping most recent), which eliminates the repeated entries caused by querying multiple worktree dirs. Added hide/clear endpoints (DELETE /api/sessions/:id, DELETE /api/sessions). Frontend: swipe-to-dismiss on individual sessions (mobile touch), "Clear" button in the section header. Made-with: Cursor
…ctions Frontend: - Extract shared types (Message, Session, ImageAttachment, etc.) to types/chat.ts - Extract utilities: groupMessages, formatRelativeTime, resizeImage, truncate to lib/ - Components now import from types/ instead of coupling to ChatView page - Wrap handlePermission in useCallback (stabilizes PermissionBanner timer) - Guard JSON.parse in WS onmessage with try/catch - Replace Record<string, any> with Record<string, unknown> - Remove unused lastPayload ref Server: - Extract content-blocks.ts: parseContentBlocks + extractToolResultText (was duplicated between streaming loop and getMessages) - Break up startChat: extract resolveWorktree, stageImages, buildPermissionHandler - Remove dead buildNotificationHeaders export from notify.ts - Replace err: any with err: unknown + instanceof checks - Update chat.test.ts exports check, remove stale comment - Add content-blocks.test.ts (7 new tests) Total: 70 tests passing, 0 lint errors, tsc clean. Made-with: Cursor
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
getSessions()deduplicates by session ID. Swipe-to-dismiss on mobile, "Clear" button in the section header.types/chat.ts, utilities tolib/, broke up the 234-linestartChatgod function, removed dead exports fromnotify.ts, tightened types (any→unknown), guardedJSON.parsein WS handler.New modules
server/session-registry.ts— session lifecycle decoupled from WebSocket lifecycleserver/tool-summary.ts— extractedsummarizeToolInput(was private in chat.ts)server/content-blocks.ts— deduplicated content block parsingfrontend/src/types/chat.ts— shared types (Message, Session, ImageAttachment, etc.)frontend/src/lib/— groupMessages, formatTime, truncate, resizeImageTest plan
Made with Cursor