diff --git a/src/renderer/src/components/browser-pane/useGrabMode.ts b/src/renderer/src/components/browser-pane/useGrabMode.ts index b3ee2580572..018fb0368fe 100644 --- a/src/renderer/src/components/browser-pane/useGrabMode.ts +++ b/src/renderer/src/components/browser-pane/useGrabMode.ts @@ -183,34 +183,6 @@ export function useGrabMode(browserPageId: string): GrabModeHook { } }, [mountedRef]) - const toggle = useCallback(() => { - if ((state === 'idle' || state === 'error') && grabTabIdRef.current === null) { - setError(null) - setPayload(null) - setContextMenu(false) - void armAndAwait() - } else { - // Disable grab mode - const targetTabId = grabTabIdRef.current ?? browserTabIdRef.current - armGenerationRef.current += 1 - void window.api.browser.setGrabMode({ - browserPageId: targetTabId, - enabled: false - }) - if (activeOpIdRef.current) { - void window.api.browser.cancelGrab({ - browserPageId: targetTabId - }) - activeOpIdRef.current = null - } - grabTabIdRef.current = null - setState('idle') - setPayload(null) - setError(null) - setContextMenu(false) - } - }, [state, armAndAwait]) - const cancel = useCallback(() => { const targetTabId = grabTabIdRef.current ?? browserTabIdRef.current armGenerationRef.current += 1 @@ -231,6 +203,17 @@ export function useGrabMode(browserPageId: string): GrabModeHook { setContextMenu(false) }, []) + const toggle = useCallback(() => { + if ((state === 'idle' || state === 'error') && grabTabIdRef.current === null) { + setError(null) + setPayload(null) + setContextMenu(false) + void armAndAwait() + } else { + cancel() + } + }, [state, armAndAwait, cancel]) + // Why: Copy re-arms so the user can quickly pick another element without // re-clicking the toolbar button. Attach to AI exits because the user's // intent is to continue in the chat, not keep selecting. diff --git a/src/renderer/src/lib/setup-script-prompt.ts b/src/renderer/src/lib/setup-script-prompt.ts index d85a3a9ec30..f25b806d1ef 100644 --- a/src/renderer/src/lib/setup-script-prompt.ts +++ b/src/renderer/src/lib/setup-script-prompt.ts @@ -4,6 +4,7 @@ import type { SetupScriptImportCandidate } from '../../../shared/setup-script-im import type { Repo, RepoHookSettings } from '../../../shared/types' import type { HookCheckResult } from '@/runtime/runtime-hooks-client' import { isRuntimeScopeForbiddenError } from '@/runtime/runtime-rpc-client' +import { hasEffectiveSetupCommand } from './setup-script-status' const SETUP_SCRIPT_PROMPT_DISMISSAL_PREFIX = 'generation-v1:' @@ -69,25 +70,6 @@ export async function inspectSetupScriptPromptState({ } } -export function hasEffectiveSetupCommand(repo: Repo, hooksResult: HookCheckResult): boolean { - const localSetup = repo.hookSettings?.scripts?.setup?.trim() - const sharedSetup = hooksResult.hooks?.scripts?.setup?.trim() - const rawPolicy = repo.hookSettings?.commandSourcePolicy - const sourcePolicy = resolveHookCommandSourcePolicy(rawPolicy, { - hasLocalScript: Boolean(localSetup) - }) - - if (sourcePolicy === 'local-only') { - return Boolean(localSetup) - } - - if (sourcePolicy === 'run-both') { - return Boolean(sharedSetup || localSetup) - } - - return Boolean(sharedSetup) -} - export function ignoresSharedSetupScripts(repo: Pick): boolean { const localSetup = repo.hookSettings?.scripts?.setup?.trim() return (