From 7801845ac4377ad4b8afea80ad8eaa0e61320838 Mon Sep 17 00:00:00 2001 From: amiagent Date: Tue, 10 Mar 2026 13:10:30 +0000 Subject: [PATCH 1/3] Remove unused utility files: create-text-node-bounds and get-text-node-at-position Both files were defined but never imported or called anywhere in the codebase. Co-Authored-By: Claude Sonnet 4.6 --- .../src/utils/create-text-node-bounds.ts | 16 -------- .../src/utils/get-text-node-at-position.ts | 38 ------------------- 2 files changed, 54 deletions(-) delete mode 100644 packages/react-grab/src/utils/create-text-node-bounds.ts delete mode 100644 packages/react-grab/src/utils/get-text-node-at-position.ts diff --git a/packages/react-grab/src/utils/create-text-node-bounds.ts b/packages/react-grab/src/utils/create-text-node-bounds.ts deleted file mode 100644 index 9c360eec4..000000000 --- a/packages/react-grab/src/utils/create-text-node-bounds.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { OverlayBounds } from "../types.js"; - -export const createTextNodeBounds = (textNode: Text): OverlayBounds => { - const range = document.createRange(); - range.selectNodeContents(textNode); - const rect = range.getBoundingClientRect(); - - return { - borderRadius: "0px", - height: rect.height, - transform: "none", - width: rect.width, - x: rect.left, - y: rect.top, - }; -}; diff --git a/packages/react-grab/src/utils/get-text-node-at-position.ts b/packages/react-grab/src/utils/get-text-node-at-position.ts deleted file mode 100644 index 5fc110156..000000000 --- a/packages/react-grab/src/utils/get-text-node-at-position.ts +++ /dev/null @@ -1,38 +0,0 @@ -const WHITESPACE_ONLY_PATTERN = /^\s*$/; - -const isPointInsideRect = ( - clientX: number, - clientY: number, - rect: DOMRect, -): boolean => - clientX >= rect.left && - clientX <= rect.right && - clientY >= rect.top && - clientY <= rect.bottom; - -export const getTextNodeAtPosition = ( - element: Element, - clientX: number, - clientY: number, -): Text | null => { - const treeWalker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT); - const range = document.createRange(); - - let currentNode = treeWalker.nextNode(); - while (currentNode) { - const textContent = currentNode.textContent; - if (textContent && !WHITESPACE_ONLY_PATTERN.test(textContent)) { - range.selectNodeContents(currentNode); - const clientRects = range.getClientRects(); - - for (let rectIndex = 0; rectIndex < clientRects.length; rectIndex++) { - if (isPointInsideRect(clientX, clientY, clientRects[rectIndex])) { - return currentNode as Text; - } - } - } - currentNode = treeWalker.nextNode(); - } - - return null; -}; From ac2e4ed2e22dbfe416f396125ef20198fa7140df Mon Sep 17 00:00:00 2001 From: amiagent Date: Tue, 10 Mar 2026 13:20:05 +0000 Subject: [PATCH 2/3] Fix inconsistent timer ID null checks in cleanup handlers Three timer ID checks used truthy checks (if (timerId)) instead of the consistent explicit null check (if (timerId !== null)) used throughout the rest of the file. While window.setTimeout() never returns 0 in practice, this inconsistency violated the established pattern and was a latent correctness risk. Co-Authored-By: Claude Sonnet 4.6 --- packages/react-grab/src/core/index.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/react-grab/src/core/index.tsx b/packages/react-grab/src/core/index.tsx index 7eb25c429..428a9de70 100644 --- a/packages/react-grab/src/core/index.tsx +++ b/packages/react-grab/src/core/index.tsx @@ -1528,7 +1528,7 @@ export const init = (rawOptions?: Options): ReactGrabAPI => { if (wasDragging) { document.body.style.userSelect = ""; } - if (keydownSpamTimerId) window.clearTimeout(keydownSpamTimerId); + if (keydownSpamTimerId !== null) window.clearTimeout(keydownSpamTimerId); autoScroller.stop(); if ( previousFocused instanceof HTMLElement && @@ -3106,9 +3106,9 @@ export const init = (rawOptions?: Options): ReactGrabAPI => { if (dragPreviewDebounceTimerId !== null) { window.clearTimeout(dragPreviewDebounceTimerId); } - if (keydownSpamTimerId) window.clearTimeout(keydownSpamTimerId); - if (toggleFeedbackTimerId) window.clearTimeout(toggleFeedbackTimerId); - if (actionCycleIdleTimeoutId) { + if (keydownSpamTimerId !== null) window.clearTimeout(keydownSpamTimerId); + if (toggleFeedbackTimerId !== null) window.clearTimeout(toggleFeedbackTimerId); + if (actionCycleIdleTimeoutId !== null) { window.clearTimeout(actionCycleIdleTimeoutId); } if (dropdownTrackingFrameId !== null) { From e0d75b3bb509186d62445c46b25f9b4a8190f4f4 Mon Sep 17 00:00:00 2001 From: amiagent Date: Tue, 10 Mar 2026 13:34:04 +0000 Subject: [PATCH 3/3] Fix copilot provider storing wrong session ID for resume MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The copilot handler was mapping browserSessionId → browserSessionId in copilotSessionMap on close, then passing this back as the --resume arg on the next run. This would send the browser's internal session ID to the copilot CLI instead of the actual copilot session ID. The fix mirrors the cursor/claude-code pattern: only set the session map if a capturedCopilotSessionId was actually obtained from the CLI output. Since the copilot CLI outputs plain text (not JSON with a session_id), this variable remains undefined and the map is never incorrectly populated. Co-Authored-By: Claude Sonnet 4.6 --- packages/provider-copilot/src/handler.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/provider-copilot/src/handler.ts b/packages/provider-copilot/src/handler.ts index 16e3e7d3f..25dea85a4 100644 --- a/packages/provider-copilot/src/handler.ts +++ b/packages/provider-copilot/src/handler.ts @@ -63,6 +63,7 @@ const runCopilotAgent = async function* ( const messageQueue: AgentMessage[] = []; let resolveWait: (() => void) | null = null; let processEnded = false; + let capturedCopilotSessionId: string | undefined; const enqueueMessage = (message: AgentMessage) => { messageQueue.push(message); @@ -87,9 +88,9 @@ const runCopilotAgent = async function* ( activeProcesses.delete(sessionId); } - if (sessionId && !childProcess.killed) { - copilotSessionMap.set(sessionId, sessionId); - lastCopilotSessionId = sessionId; + if (sessionId && !childProcess.killed && capturedCopilotSessionId) { + copilotSessionMap.set(sessionId, capturedCopilotSessionId); + lastCopilotSessionId = capturedCopilotSessionId; } processEnded = true;