From d3cd46a8101959ceec8c5967c908c71604c0e08b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 10 Apr 2026 10:34:42 +0000 Subject: [PATCH 1/2] fix: update lockfile signatures and Nix hash --- nix/package.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nix/package.nix b/nix/package.nix index db9dd06ca..598e6e881 100644 --- a/nix/package.nix +++ b/nix/package.nix @@ -42,7 +42,7 @@ buildNpmPackage rec { # To update: run `nix build` with lib.fakeHash, copy the `got:` hash. # CI auto-updates this when package-lock.json changes (see .github/workflows/). - npmDepsHash = "sha256-gyCcVTlgLk8+G/OtwZT/GomN2lYe7uEcDoLp1ZQoc5M="; + npmDepsHash = "sha256-6NXZBZwIxCBYxaTe+lq6D8uNaJzL3+z/VUodVS0sS9o="; # Prevent onnxruntime-node's install script from running during automatic # npm rebuild (it tries to download from api.nuget.org, which fails in the sandbox). From ba1ecedca3732427578eeba1ed332d802574f562 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Fri, 10 Apr 2026 18:51:46 +0700 Subject: [PATCH 2/2] feat: middle-click to close tabs on desktop (#232) Add useMiddleClickClose hook that listens for auxclick (button === 1) events on web, enabling middle-click-to-close behavior on tab chips. --- .../workspace/workspace-desktop-tabs-row.tsx | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx b/packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx index 110f01970..93493da3b 100644 --- a/packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx +++ b/packages/app/src/screens/workspace/workspace-desktop-tabs-row.tsx @@ -1,4 +1,12 @@ -import { useCallback, useMemo, useState, type Dispatch, type SetStateAction } from "react"; +import { + useCallback, + useEffect, + useMemo, + useRef, + useState, + type Dispatch, + type SetStateAction, +} from "react"; import { ActivityIndicator, Platform, @@ -101,6 +109,27 @@ function getFallbackTabLabel(tab: WorkspaceTabDescriptor): string { return "Agent"; } +function useMiddleClickClose(onClose: () => void) { + const ref = useRef(null); + + useEffect(() => { + const node = ref.current as unknown as HTMLElement | null; + if (!node) return; + + function handleAuxClick(event: MouseEvent) { + if (event.button === 1) { + event.preventDefault(); + onClose(); + } + } + + node.addEventListener("auxclick", handleAuxClick); + return () => node.removeEventListener("auxclick", handleAuxClick); + }, [onClose]); + + return ref; +} + function TabChip({ tab, isActive, @@ -140,6 +169,9 @@ function TabChip({ }) { const { theme } = useUnistyles(); const { closeButtonTestId, contextMenuTestId, menuEntries } = resolvedTab; + const middleClickRef = useMiddleClickClose( + useCallback(() => void onCloseTab(tab.tabId), [onCloseTab, tab.tabId]), + ); const [hovered, setHovered] = useState(false); const isHighlighted = isActive || hovered || isCloseHovered; const closeButtonDragBlockers = @@ -155,6 +187,7 @@ function TabChip({ : undefined; return ( + @@ -325,6 +358,7 @@ function TabChip({ )} + ); }