mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-13 02:41:50 +08:00
feat(explorer): async task execution, CLI selector fix, WebSocket frame handling
- Task queue now executes tasks in parallel using Promise.all - addFolderToQueue uses selected CLI tool instead of hardcoded 'gemini' - Added CSS styles for queue-cli-selector toolbar - Force refresh notification list after all tasks complete - Fixed WebSocket frame parsing to handle Ping/Pong control frames - Respond to Ping with Pong, ignore other control frames - Eliminates garbled characters in WebSocket logs
This commit is contained in:
@@ -507,9 +507,31 @@ function handleWebSocketUpgrade(req, socket, head) {
|
|||||||
// Handle incoming messages
|
// Handle incoming messages
|
||||||
socket.on('data', (buffer) => {
|
socket.on('data', (buffer) => {
|
||||||
try {
|
try {
|
||||||
const message = parseWebSocketFrame(buffer);
|
const frame = parseWebSocketFrame(buffer);
|
||||||
if (message) {
|
if (!frame) return;
|
||||||
console.log('[WS] Received:', message);
|
|
||||||
|
const { opcode, payload } = frame;
|
||||||
|
|
||||||
|
switch (opcode) {
|
||||||
|
case 0x1: // Text frame
|
||||||
|
if (payload) {
|
||||||
|
console.log('[WS] Received:', payload);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x8: // Close frame
|
||||||
|
socket.end();
|
||||||
|
break;
|
||||||
|
case 0x9: // Ping frame - respond with Pong
|
||||||
|
const pongFrame = Buffer.alloc(2);
|
||||||
|
pongFrame[0] = 0x8A; // Pong opcode with FIN bit
|
||||||
|
pongFrame[1] = 0x00; // No payload
|
||||||
|
socket.write(pongFrame);
|
||||||
|
break;
|
||||||
|
case 0xA: // Pong frame - ignore
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Ignore other frame types (binary, continuation)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Ignore parse errors
|
// Ignore parse errors
|
||||||
@@ -529,10 +551,18 @@ function handleWebSocketUpgrade(req, socket, head) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse WebSocket frame (simplified)
|
* Parse WebSocket frame (simplified)
|
||||||
|
* Returns { opcode, payload } or null
|
||||||
*/
|
*/
|
||||||
function parseWebSocketFrame(buffer) {
|
function parseWebSocketFrame(buffer) {
|
||||||
if (buffer.length < 2) return null;
|
if (buffer.length < 2) return null;
|
||||||
|
|
||||||
|
const firstByte = buffer[0];
|
||||||
|
const opcode = firstByte & 0x0f; // Extract opcode (bits 0-3)
|
||||||
|
|
||||||
|
// Opcode types:
|
||||||
|
// 0x0 = continuation, 0x1 = text, 0x2 = binary
|
||||||
|
// 0x8 = close, 0x9 = ping, 0xA = pong
|
||||||
|
|
||||||
const secondByte = buffer[1];
|
const secondByte = buffer[1];
|
||||||
const isMasked = (secondByte & 0x80) !== 0;
|
const isMasked = (secondByte & 0x80) !== 0;
|
||||||
let payloadLength = secondByte & 0x7f;
|
let payloadLength = secondByte & 0x7f;
|
||||||
@@ -560,7 +590,7 @@ function parseWebSocketFrame(buffer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return payload.toString('utf8');
|
return { opcode, payload: payload.toString('utf8') };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -836,6 +836,12 @@ async function startTaskQueue() {
|
|||||||
'Explorer'
|
'Explorer'
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Force refresh notification list to ensure all notifications are displayed
|
||||||
|
if (typeof renderGlobalNotifications === 'function') {
|
||||||
|
renderGlobalNotifications();
|
||||||
|
updateGlobalNotifBadge();
|
||||||
|
}
|
||||||
|
|
||||||
// Re-enable start button if there are pending tasks
|
// Re-enable start button if there are pending tasks
|
||||||
const hasPending = updateTaskQueue.some(t => t.status === 'pending');
|
const hasPending = updateTaskQueue.some(t => t.status === 'pending');
|
||||||
document.getElementById('startQueueBtn').disabled = !hasPending;
|
document.getElementById('startQueueBtn').disabled = !hasPending;
|
||||||
|
|||||||
Reference in New Issue
Block a user