From be4b3ffad3156983224ff56f4bcb7a8e4e2acacc Mon Sep 17 00:00:00 2001 From: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Date: Thu, 29 Oct 2026 14:17:33 -0700 Subject: [PATCH] fix(ci): resolve existing max-lines and command fixture violations (#36096) --- .../describe-page/browser-page-types.ts | 22 ++++++++ .../components/sidebar/WorktreeCardAgents.tsx | 48 +----------------- .../sidebar/use-worktree-agent-activation.ts | 50 +++++++++++++++++++ 3 files changed, 74 insertions(+), 46 deletions(-) create mode 100644 src/renderer/src/components/sidebar/use-worktree-agent-activation.ts diff --git a/src/renderer/src/components/browser-pane/describe-page/browser-page-types.ts b/src/renderer/src/components/browser-pane/describe-page/browser-page-types.ts index 8bb7d4f8df3..6e335704197 100644 --- a/src/renderer/src/components/browser-pane/describe-page/browser-page-types.ts +++ b/src/renderer/src/components/browser-pane/describe-page/browser-page-types.ts @@ -113,3 +113,25 @@ export type ClientHostedBrowserPagePaneProps = { onUpdatePageState: (tabId: string, updates: BrowserTabPageState) => void onSetUrl: BrowserPageUrlSetter } + +export type BrowserPageGrabAnnotations = { + grabIntent: GrabIntent + startGrabIntent: (nextIntent: GrabIntent) => void + pendingAnnotationPayload: BrowserGrabPayload | null + setPendingAnnotationPayload: Dispatch> + grabToast: BrowserPageGrabToastState | null + setGrabToast: Dispatch> + grabToastTimerRef: MutableRefObject | undefined> + dismissGrabToast: () => void + handleGrabCopy: () => void + handleGrabCopyScreenshot: () => void + grabMenuActionTakenRef: MutableRefObject + handleAddBrowserAnnotation: ( + comment: string, + intent: BrowserAnnotationIntent, + imagePaths?: string[] + ) => void + handleCancelPendingBrowserAnnotation: () => void + cancelPendingBrowserCapture: () => void + handleGrabActionShortcut: (key: 'c' | 's') => void +} diff --git a/src/renderer/src/components/sidebar/WorktreeCardAgents.tsx b/src/renderer/src/components/sidebar/WorktreeCardAgents.tsx index 2d41a796cdd..eed0c3a316a 100644 --- a/src/renderer/src/components/sidebar/WorktreeCardAgents.tsx +++ b/src/renderer/src/components/sidebar/WorktreeCardAgents.tsx @@ -1,9 +1,7 @@ +import { useWorktreeAgentActivation } from './use-worktree-agent-activation' import React, { useCallback, useLayoutEffect, useMemo, useRef } from 'react' import { useShallow } from 'zustand/react/shallow' import { useAppStore } from '@/store' -import { activateAndRevealWorktree } from '@/lib/worktree-activation' -import { activateTabAndFocusPane } from '@/lib/activate-tab-and-focus-pane' -import { activateTerminalTabOnOwner } from '@/lib/terminal-tab-owner-activation' import DashboardAgentRow from '@/components/dashboard/DashboardAgentRow' import { useNow } from '@/hooks/use-now' import { deriveRunningAgentSendTargets } from '@/lib/running-agent-targets' @@ -14,8 +12,6 @@ import { import { useWorktreeAgentRows } from './useWorktreeAgentRows' import { cn } from '@/lib/utils' import type { DashboardAgentRow as DashboardAgentRowData } from '@/components/dashboard/useDashboardData' -import { parsePaneKey } from '../../../../shared/stable-pane-id' -import { dismissStaleAgentRowByKey } from '../terminal-pane/stale-agent-row' import { useFocusedAgentPaneKey } from './focused-agent-row-highlight' import { CompactAgentExpansion, @@ -29,7 +25,6 @@ import { useWorktreeAgentExpansionState } from './worktree-card-agents-expansion import { translate } from '@/i18n/i18n' import { agentSendDisabledReasonLabel } from '@/lib/agent-send-disabled-reason-label' import { useUiLanguageRevision } from '@/i18n/use-ui-language-revision' -import { activateStructuredAgentSessionTab } from '@/lib/agent-session/structured-agent-session-tab-activation' import { activateRetainedAgentRow } from './activate-retained-agent-row' import { selectAgentRowsUnread } from './worktree-card-agent-ack-inputs' import { opensClaudeParentConversation } from '@/lib/claude-agent-row-view' @@ -81,7 +76,6 @@ const WorktreeCardAgentsBody = React.memo(function WorktreeCardAgentsBody({ const { targetMode: agentSendPopoverTargetMode, agentStatusEpoch } = useAppStore( useShallow((s) => selectSendTargetControlInputs(s, worktreeId)) ) - // Use a stable empty selector outside our send popover so unrelated title/status churn cannot wake idle cards. const sendTargetInputs = useAppStore(useShallow((s) => selectSendTargetInputs(s, worktreeId))) const sendPromptToSidebarAgentTarget = useAppStore((s) => s.sendPromptToSidebarAgentTarget) const focusedAgentPaneKey = useFocusedAgentPaneKey(worktreeId) @@ -154,45 +148,7 @@ const WorktreeCardAgentsBody = React.memo(function WorktreeCardAgentsBody({ [sendPromptToSidebarAgentTarget] ) - const handleActivateAgentTab = useCallback( - (tabId: string, paneKey: string) => { - const parsed = parsePaneKey(paneKey) - if (!parsed) { - // Legacy/malformed pane keys cannot resolve after replay; discard stale rows rather than guessing. - console.warn('[WorktreeCardAgents] malformed paneKey, skipping pane focus', paneKey) - dismissStaleAgentRowByKey(paneKey) - return - } - if (parsed.tabId !== tabId) { - console.warn('[WorktreeCardAgents] paneKey tabId mismatch, dismissing row', { - tabId, - paneKey - }) - dismissStaleAgentRowByKey(paneKey) - return - } - // Use shared activation for cross-repo reveal and navigation history. - activateAndRevealWorktree(worktreeId) - const tabs = useAppStore.getState().tabsByWorktree[worktreeId] ?? [] - if (tabs.some((t) => t.id === tabId)) { - activateTabAndFocusPane(tabId, parsed.leafId, { - ackPaneKeyOnSuccess: paneKey, - flashFocusedPane: true, - scrollToBottomIfOutputSinceLastView: true - }) - activateTerminalTabOnOwner(worktreeId, tabId, parsed.leafId) - } else if (!activateStructuredAgentSessionTab({ worktreeId, tabId })) { - const liveEntry = useAppStore.getState().agentStatusByPaneKey[paneKey] - if (liveEntry?.worktreeId === worktreeId) { - // Live worker status can precede tab hydration; retain the row and activate its owning terminal. - activateTerminalTabOnOwner(worktreeId, tabId, parsed.leafId) - return - } - dismissStaleAgentRowByKey(paneKey) - } - }, - [worktreeId] - ) + const handleActivateAgentTab = useWorktreeAgentActivation(worktreeId) const handleActivateRetainedAgent = useCallback( (tabId: string, paneKey: string) => activateRetainedAgentRow(worktreeId, tabId, paneKey), [worktreeId] diff --git a/src/renderer/src/components/sidebar/use-worktree-agent-activation.ts b/src/renderer/src/components/sidebar/use-worktree-agent-activation.ts new file mode 100644 index 00000000000..c19404427c4 --- /dev/null +++ b/src/renderer/src/components/sidebar/use-worktree-agent-activation.ts @@ -0,0 +1,50 @@ +import { useCallback } from 'react' +import { useAppStore } from '@/store' +import { activateAndRevealWorktree } from '@/lib/worktree-activation' +import { activateTabAndFocusPane } from '@/lib/activate-tab-and-focus-pane' +import { activateTerminalTabOnOwner } from '@/lib/terminal-tab-owner-activation' +import { parsePaneKey } from '../../../../shared/stable-pane-id' +import { dismissStaleAgentRowByKey } from '../terminal-pane/stale-agent-row' +import { activateStructuredAgentSessionTab } from '@/lib/agent-session/structured-agent-session-tab-activation' + +export function useWorktreeAgentActivation(worktreeId: string) { + return useCallback( + (tabId: string, paneKey: string) => { + const parsed = parsePaneKey(paneKey) + if (!parsed) { + // Legacy/malformed pane keys cannot resolve after replay; discard stale rows rather than guessing. + console.warn('[WorktreeCardAgents] malformed paneKey, skipping pane focus', paneKey) + dismissStaleAgentRowByKey(paneKey) + return + } + if (parsed.tabId !== tabId) { + console.warn('[WorktreeCardAgents] paneKey tabId mismatch, dismissing row', { + tabId, + paneKey + }) + dismissStaleAgentRowByKey(paneKey) + return + } + // Use shared activation for cross-repo reveal and navigation history. + activateAndRevealWorktree(worktreeId) + const tabs = useAppStore.getState().tabsByWorktree[worktreeId] ?? [] + if (tabs.some((t) => t.id === tabId)) { + activateTabAndFocusPane(tabId, parsed.leafId, { + ackPaneKeyOnSuccess: paneKey, + flashFocusedPane: true, + scrollToBottomIfOutputSinceLastView: true + }) + activateTerminalTabOnOwner(worktreeId, tabId, parsed.leafId) + } else if (!activateStructuredAgentSessionTab({ worktreeId, tabId })) { + const liveEntry = useAppStore.getState().agentStatusByPaneKey[paneKey] + if (liveEntry?.worktreeId === worktreeId) { + // Live worker status can precede tab hydration; retain the row and activate its owning terminal. + activateTerminalTabOnOwner(worktreeId, tabId, parsed.leafId) + return + } + dismissStaleAgentRowByKey(paneKey) + } + }, + [worktreeId] + ) +}