mirror of
https://github.com/stablyai/orca.git
synced 2026-09-28 08:02:43 +00:00
fix: guard browser use cli async state (#3567)
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/* eslint-disable max-lines -- Why: Browser Use setup keeps enablement, CLI registration, skill install, cookie import, examples, and interaction tracking in one pane so the three-step setup state stays coherent. */
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { Import, Loader2, MousePointerClick } from 'lucide-react'
|
||||
import { toast } from 'sonner'
|
||||
import type { CliInstallStatus } from '../../../../shared/cli-install-types'
|
||||
@@ -58,6 +58,20 @@ export function BrowserUseSetup({
|
||||
const [cliStatus, setCliStatus] = useState<CliInstallStatus | null>(null)
|
||||
const [cliLoading, setCliLoading] = useState(true)
|
||||
const [cliBusy, setCliBusy] = useState(false)
|
||||
const mountedRef = useRef(true)
|
||||
|
||||
useEffect(() => {
|
||||
mountedRef.current = true
|
||||
return () => {
|
||||
mountedRef.current = false
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleCliStatusChange = useCallback((nextStatus: CliInstallStatus): void => {
|
||||
if (mountedRef.current) {
|
||||
setCliStatus(nextStatus)
|
||||
}
|
||||
}, [])
|
||||
|
||||
// Why: the toggle gates only whether we show the setup instructions. We
|
||||
// persist it in localStorage instead of global settings because it has no
|
||||
@@ -75,16 +89,20 @@ export function BrowserUseSetup({
|
||||
}
|
||||
}
|
||||
|
||||
const refreshCli = async (): Promise<void> => {
|
||||
const refreshCli = useCallback(async (): Promise<void> => {
|
||||
setCliLoading(true)
|
||||
try {
|
||||
setCliStatus(await window.api.cli.getInstallStatus())
|
||||
handleCliStatusChange(await window.api.cli.getInstallStatus())
|
||||
} catch (error) {
|
||||
toast.error(error instanceof Error ? error.message : 'Failed to load CLI status.')
|
||||
if (mountedRef.current) {
|
||||
toast.error(error instanceof Error ? error.message : 'Failed to load CLI status.')
|
||||
}
|
||||
} finally {
|
||||
setCliLoading(false)
|
||||
if (mountedRef.current) {
|
||||
setCliLoading(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [handleCliStatusChange])
|
||||
|
||||
useEffect(() => {
|
||||
// Why: skip IPC work when the feature is toggled off — the component
|
||||
@@ -94,7 +112,7 @@ export function BrowserUseSetup({
|
||||
}
|
||||
void refreshCli()
|
||||
void fetchBrowserSessionProfiles()
|
||||
}, [browserUseEnabled, fetchBrowserSessionProfiles])
|
||||
}, [browserUseEnabled, fetchBrowserSessionProfiles, refreshCli])
|
||||
|
||||
const defaultProfile = browserSessionProfiles.find((p) => p.id === 'default')
|
||||
// Why: this step explicitly imports into the default profile, so completion
|
||||
@@ -121,13 +139,15 @@ export function BrowserUseSetup({
|
||||
setCliBusy(true)
|
||||
try {
|
||||
const next = await ensureOrcaCliAvailableForAgentSkillTerminal({
|
||||
onStatusChange: setCliStatus
|
||||
onStatusChange: handleCliStatusChange
|
||||
})
|
||||
if (isOrcaCliAvailableOnPath(next)) {
|
||||
if (mountedRef.current && isOrcaCliAvailableOnPath(next)) {
|
||||
toast.success('Registered the Orca CLI in PATH.')
|
||||
}
|
||||
} finally {
|
||||
setCliBusy(false)
|
||||
if (mountedRef.current) {
|
||||
setCliBusy(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,7 +348,9 @@ export function BrowserUseSetup({
|
||||
preInstallNotice={AGENT_SKILL_CLI_PREREQUISITE_NOTICE}
|
||||
onBeforeOpenTerminal={async () => {
|
||||
useAppStore.getState().recordFeatureInteraction('agent-browser-setup')
|
||||
await ensureOrcaCliAvailableForAgentSkillTerminal({ onStatusChange: setCliStatus })
|
||||
await ensureOrcaCliAvailableForAgentSkillTerminal({
|
||||
onStatusChange: handleCliStatusChange
|
||||
})
|
||||
}}
|
||||
onRecheck={refreshSkill}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user