Skip to content

Commit 2e6ea6f

Browse files
authored
fix: improve connection reliability with better handshake detection (#133)
# Improve Claude connection reliability and queue processing This PR enhances the connection handling and queue processing for Claude Code: - Increases the connection wait delay from 200ms to 600ms to ensure Claude is fully ready before sending queued mentions - Implements a more robust connection check that verifies WebSocket handshake completion - Adds progressive polling after connection to ensure handshake is complete - Increases the delay between sequential message sends to 25ms (from 10ms) to prevent overwhelming the WebSocket connection - Adds more detailed logging for connection and queue processing states - Implements a retry mechanism that polls until handshake completes when triggered by a new connection These changes should significantly improve reliability when sending multiple mentions to Claude, especially immediately after connection.
1 parent 8fdb815 commit 2e6ea6f

File tree

2 files changed

+32
-7
lines changed

2 files changed

+32
-7
lines changed

lua/claudecode/config.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ M.defaults = {
1717
-- When true, focus Claude terminal after a successful send while connected
1818
focus_after_send = false,
1919
visual_demotion_delay_ms = 50, -- Milliseconds to wait before demoting a visual selection
20-
connection_wait_delay = 200, -- Milliseconds to wait after connection before sending queued @ mentions
20+
connection_wait_delay = 600, -- Milliseconds to wait after connection before sending queued @ mentions
2121
connection_timeout = 10000, -- Maximum time to wait for Claude Code to connect (milliseconds)
2222
queue_timeout = 5000, -- Maximum time to keep @ mentions in queue (milliseconds)
2323
diff_opts = {

lua/claudecode/init.lua

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,21 @@ function M.is_claude_connected()
4747

4848
local server_module = require("claudecode.server.init")
4949
local status = server_module.get_status()
50-
return status.running and status.client_count > 0
50+
if not status.running then
51+
return false
52+
end
53+
54+
-- Prefer handshake-aware check when client info is available; otherwise fall back to client_count
55+
if status.clients and #status.clients > 0 then
56+
for _, info in ipairs(status.clients) do
57+
if (info.state == "connected" or info.handshake_complete == true) and info.handshake_complete == true then
58+
return true
59+
end
60+
end
61+
return false
62+
else
63+
return status.client_count and status.client_count > 0
64+
end
5165
end
5266

5367
---Clear the mention queue and stop any pending timer
@@ -149,8 +163,16 @@ function M.process_mention_queue(from_new_connection)
149163
end
150164

151165
if not M.is_claude_connected() then
152-
-- Still disconnected, wait for connection
153-
logger.debug("queue", "Claude not connected, keeping " .. #M.state.mention_queue .. " mentions queued")
166+
-- Still disconnected or handshake not complete yet, wait for readiness
167+
logger.debug("queue", "Claude not ready (no handshake). Keeping ", #M.state.mention_queue, " mentions queued")
168+
169+
-- If triggered by a new connection, poll until handshake completes (bounded by connection_timeout timer)
170+
if from_new_connection then
171+
local retry_delay = math.max(50, math.floor((M.state.config.connection_wait_delay or 200) / 4))
172+
vim.defer_fn(function()
173+
M.process_mention_queue(true)
174+
end, retry_delay)
175+
end
154176
return
155177
end
156178

@@ -173,7 +195,7 @@ function M.process_mention_queue(from_new_connection)
173195

174196
logger.debug("queue", "Processing " .. #mentions_to_send .. " queued @ mentions")
175197

176-
-- Send mentions with 10ms delay between each to prevent WebSocket buffer overflow
198+
-- Send mentions with a small delay between each to prevent WebSocket/extension overwhelm
177199
local function send_mention_sequential(index)
178200
if index > #mentions_to_send then
179201
logger.debug("queue", "All queued mentions sent successfully")
@@ -204,19 +226,22 @@ function M.process_mention_queue(from_new_connection)
204226

205227
-- Process next mention with delay
206228
if index < #mentions_to_send then
229+
local inter_message_delay = 25 -- ms
207230
vim.defer_fn(function()
208231
send_mention_sequential(index + 1)
209-
end, 10) -- 10ms delay between mentions
232+
end, inter_message_delay)
210233
end
211234
end
212235

213236
-- Apply delay for new connections, send immediately for debounced processing
214237
if #mentions_to_send > 0 then
215238
if from_new_connection then
216239
-- Wait for connection_wait_delay when processing queue after new connection
240+
local initial_delay = (M.state.config and M.state.config.connection_wait_delay) or 200
241+
logger.debug("queue", "Waiting ", initial_delay, "ms after connect before flushing queue")
217242
vim.defer_fn(function()
218243
send_mention_sequential(1)
219-
end, M.state.config.connection_wait_delay)
244+
end, initial_delay)
220245
else
221246
-- Send immediately for debounced processing (Claude already connected)
222247
send_mention_sequential(1)

0 commit comments

Comments
 (0)