From 19d7156161b95010efc28463f45e59b2ccb907e1 Mon Sep 17 00:00:00 2001 From: Jinwoo-H Date: Sun, 20 Sep 2026 23:38:53 -0400 Subject: [PATCH] refactor(terminal): stop handing the reveal caller back its own worktree key The target carried the event's key when there was no owner row, which is the caller's argument returned to it. Null now says 'mint', and the bridge falls back to the event's key in one place. --- .../terminal-presentation-ipc-bridge.ts | 5 ++-- .../src/lib/terminal-reveal-tab-adoption.ts | 27 +++++-------------- 2 files changed, 8 insertions(+), 24 deletions(-) diff --git a/src/renderer/src/hooks/ipc-events/terminal-presentation-ipc-bridge.ts b/src/renderer/src/hooks/ipc-events/terminal-presentation-ipc-bridge.ts index 3f4fcc58b6c..852889c4478 100644 --- a/src/renderer/src/hooks/ipc-events/terminal-presentation-ipc-bridge.ts +++ b/src/renderer/src/hooks/ipc-events/terminal-presentation-ipc-bridge.ts @@ -57,7 +57,6 @@ export function registerTerminalPresentationIpcBridge(unsubs: (() => void)[]): v // Why: a split pane revealed from mobile is only bound in the persisted layout until // its pane mounts, and its row can sit under another worktree key (#10486, STA-7961). const revealTarget = resolveTerminalRevealTarget(store, { - worktreeId, ...(ptyId ? { ptyId } : {}), ...(tabId !== undefined ? { tabId } : {}), ...(leafId ? { leafId } : {}), @@ -65,11 +64,11 @@ export function registerTerminalPresentationIpcBridge(unsubs: (() => void)[]): v }) // Why: every surfacing site below must use the owner's key, not the event's, or // verifyTerminalRevealIdentity looks the tab up under a key that does not hold it. - const ownerWorktreeId = revealTarget.ownerWorktreeId + const ownerWorktreeId = revealTarget?.worktreeId ?? worktreeId if (shouldActivate) { activateTerminalInitiatedWorktree(store, ownerWorktreeId) } - const reusedTab = revealTarget.tab + const reusedTab = revealTarget?.tab const tab = reusedTab ?? (ptyId diff --git a/src/renderer/src/lib/terminal-reveal-tab-adoption.ts b/src/renderer/src/lib/terminal-reveal-tab-adoption.ts index 05c1457714c..797f0467d7c 100644 --- a/src/renderer/src/lib/terminal-reveal-tab-adoption.ts +++ b/src/renderer/src/lib/terminal-reveal-tab-adoption.ts @@ -75,30 +75,15 @@ export function resolveTerminalRevealTabAdoption( return null } -export type TerminalRevealTargetRequest = { - worktreeId: string - ptyId?: string - tabId?: string - leafId?: string - splitFromLeafId?: string -} - -export type TerminalRevealTarget = { - /** The row to reuse: the PTY or leaf owner, else a split reveal's parent row. */ - tab: TerminalTab | undefined - /** The worktree key the reused row is filed under; the event's key when minting. */ - ownerWorktreeId: string -} - /** - * The tab a reveal should land on, and the worktree key to surface it under. Ownership is - * tab-keyed, so the owning row can sit under a worktree key other than the event's — surfacing - * under the event's key then fails `verifyTerminalRevealIdentity` (STA-7961). + * The row a reveal should land on, and the worktree key it is filed under; null to mint. Ownership + * is tab-keyed, so the owning row can sit under a key other than the event's — surfacing under the + * event's key then fails `verifyTerminalRevealIdentity` (STA-7961). */ export function resolveTerminalRevealTarget( state: TerminalRevealAdoptionState, - request: TerminalRevealTargetRequest -): TerminalRevealTarget { + request: { ptyId?: string; tabId?: string; leafId?: string; splitFromLeafId?: string } +): { tab: TerminalTab; worktreeId: string } | null { const adoptedTabId = request.ptyId ? resolveTerminalRevealTabAdoption(state, { ptyId: request.ptyId, @@ -119,5 +104,5 @@ export function resolveTerminalRevealTarget( if (isSplitReveal && !adoptedRow) { throw new Error(`Terminal tab ${request.tabId} not found`) } - return { tab: adoptedRow?.tab, ownerWorktreeId: adoptedRow?.worktreeId ?? request.worktreeId } + return adoptedRow }