perf(renderer): defer terminal quick command host work

This commit is contained in:
Neil
2026-08-09 23:26:44 -07:00
parent 016df33f00
commit a185506efa
3 changed files with 146 additions and 46 deletions
@@ -824,26 +824,6 @@ function TerminalPane(
: quickCommandRepoId
? 'This Repo'
: null
const {
hosts: quickCommandHosts,
refreshRemoteHost: refreshQuickCommandRemoteHost,
remoteHostLoadFailed: quickCommandHostLoadFailed,
remoteHostPending: quickCommandHostOwnershipPending
} = useTerminalQuickCommandHosts(worktreeId)
const visibleQuickCommandHosts = quickCommandHosts.map((host) => {
const commands = host.commands.filter(isTerminalQuickCommandComplete)
return {
globalCommands: commands.filter(
(command) => getTerminalQuickCommandScope(command).type === 'global'
),
hostId: host.hostId,
label: host.label,
repoCommands: commands.filter((command) => {
const scope = getTerminalQuickCommandScope(command)
return scope.type === 'repo' && terminalQuickCommandMatchesRepo(command, quickCommandRepoId)
})
}
})
const quickCommandGroupId =
useAppStore(
(s) =>
@@ -2569,6 +2549,32 @@ function TerminalPane(
forceBracketedMultilineTextPaste,
rightClickToPaste
})
const {
hosts: quickCommandHosts,
refreshRemoteHost: refreshQuickCommandRemoteHost,
remoteHostLoadFailed: quickCommandHostLoadFailed,
remoteHostPending: quickCommandHostOwnershipPending
} = useTerminalQuickCommandHosts(worktreeId, contextMenu.open)
const visibleQuickCommandHosts = useMemo(
() =>
quickCommandHosts.map((host) => {
const commands = host.commands.filter(isTerminalQuickCommandComplete)
return {
globalCommands: commands.filter(
(command) => getTerminalQuickCommandScope(command).type === 'global'
),
hostId: host.hostId,
label: host.label,
repoCommands: commands.filter((command) => {
const scope = getTerminalQuickCommandScope(command)
return (
scope.type === 'repo' && terminalQuickCommandMatchesRepo(command, quickCommandRepoId)
)
})
}
}),
[quickCommandHosts, quickCommandRepoId]
)
useEffect(() => {
if (contextMenu.open) {
refreshQuickCommandRemoteHost()
@@ -11,18 +11,23 @@ import type { RuntimeTerminalQuickCommands } from '@/store/slices/terminal-quick
const testState = vi.hoisted(() => ({
executionHostId: 'runtime:build' as ExecutionHostId,
loadRuntimeTerminalQuickCommands: vi.fn(async () => {}),
resolveExecutionHostId: vi.fn(() => 'runtime:build' as ExecutionHostId),
runtimeEnvironments: [] as { id: string; name: string }[],
runtimeStatusByEnvironmentId: new Map<string, { connectionGeneration?: number }>(),
runtimeTerminalQuickCommands: new Map<string, RuntimeTerminalQuickCommands>(),
settings: null as GlobalSettings | null
settings: null as GlobalSettings | null,
subscribedSelectors: [] as ((state: unknown) => unknown)[]
}))
vi.mock('@/store', () => ({
useAppStore: (selector: (state: typeof testState) => unknown) => selector(testState)
useAppStore: (selector: (state: typeof testState) => unknown) => {
testState.subscribedSelectors.push(selector as (state: unknown) => unknown)
return selector(testState)
}
}))
vi.mock('@/lib/worktree-runtime-owner', () => ({
getExecutionHostIdForWorktree: () => testState.executionHostId
getExecutionHostIdForWorktree: () => testState.resolveExecutionHostId()
}))
import {
@@ -34,12 +39,16 @@ import {
} from './use-terminal-quick-command-hosts'
let renderedHosts: TerminalQuickCommandHost[] = []
let renderedExecutionHostId: ExecutionHostId = 'local'
let refreshRemoteHost = (): void => {}
let remoteHostLoadFailed = false
let remoteHostPending = false
function Probe(): null {
const result = useTerminalQuickCommandHosts('worktree-1')
function Probe({ enabled = true }: { enabled?: boolean }): null {
const result = useTerminalQuickCommandHosts('worktree-1', enabled)
renderedExecutionHostId = result.executionHostId
renderedHosts = result.hosts
refreshRemoteHost = result.refreshRemoteHost
remoteHostLoadFailed = result.remoteHostLoadFailed
remoteHostPending = result.remoteHostPending
return null
@@ -51,10 +60,13 @@ describe('useTerminalQuickCommandHosts', () => {
beforeEach(() => {
testState.executionHostId = 'runtime:build'
testState.loadRuntimeTerminalQuickCommands.mockClear()
testState.resolveExecutionHostId.mockClear()
testState.resolveExecutionHostId.mockImplementation(() => testState.executionHostId)
testState.runtimeEnvironments = [{ id: 'build', name: 'Build Server' }]
testState.runtimeStatusByEnvironmentId = new Map([['build', { connectionGeneration: 4 }]])
testState.runtimeTerminalQuickCommands = new Map()
testState.settings = getDefaultSettings('/tmp')
testState.subscribedSelectors = []
renderedHosts = []
remoteHostLoadFailed = false
remoteHostPending = false
@@ -75,6 +87,37 @@ describe('useTerminalQuickCommandHosts', () => {
).toBe(true)
})
it('skips host resolution and remote loading while disabled', async () => {
await act(async () => root.render(createElement(Probe, { enabled: false })))
const disabledHosts = renderedHosts
expect(testState.subscribedSelectors).toHaveLength(1)
for (let write = 0; write < 1_000; write += 1) {
testState.subscribedSelectors[0](testState)
}
refreshRemoteHost()
expect(renderedExecutionHostId).toBe('local')
expect(renderedHosts).toEqual([])
expect(remoteHostLoadFailed).toBe(false)
expect(remoteHostPending).toBe(false)
expect(testState.resolveExecutionHostId).not.toHaveBeenCalled()
expect(testState.loadRuntimeTerminalQuickCommands).not.toHaveBeenCalled()
testState.executionHostId = 'runtime:other'
await act(async () => root.render(createElement(Probe, { enabled: false })))
expect(renderedHosts).toBe(disabledHosts)
expect(testState.resolveExecutionHostId).not.toHaveBeenCalled()
expect(testState.loadRuntimeTerminalQuickCommands).not.toHaveBeenCalled()
testState.executionHostId = 'runtime:build'
await act(async () => root.render(createElement(Probe)))
expect(testState.resolveExecutionHostId).toHaveBeenCalledOnce()
expect(testState.loadRuntimeTerminalQuickCommands).toHaveBeenCalledWith('build')
})
it.each([
{
name: 'unsupported',
@@ -1,4 +1,5 @@
import { useCallback, useEffect, useMemo } from 'react'
import { useShallow } from 'zustand/react/shallow'
import type { GlobalSettings, TerminalQuickCommand } from '../../../shared/types'
import {
LOCAL_EXECUTION_HOST_ID,
@@ -9,6 +10,10 @@ import { getHostDisplayLabelOverrides } from '../../../shared/host-setting-overr
import { buildExecutionHostRegistry } from '../../../shared/execution-host-registry'
import type { PublicKnownRuntimeEnvironment } from '../../../shared/runtime-environments'
import { useAppStore } from '@/store'
import type {
RuntimeTerminalQuickCommands,
TerminalQuickCommandHostsSlice
} from '@/store/slices/terminal-quick-command-hosts'
import { getExecutionHostIdForWorktree } from '@/lib/worktree-runtime-owner'
export type TerminalQuickCommandHost = {
@@ -31,6 +36,30 @@ export type HostedTerminalQuickCommand = {
key: string
}
type TerminalQuickCommandHostState = {
executionHostId: ExecutionHostId
loadRemote: TerminalQuickCommandHostsSlice['loadRuntimeTerminalQuickCommands'] | null
remoteConnectionGeneration: number
remoteEnvironmentId: string | null
remoteHostId: ExecutionHostId | null
remoteState: RuntimeTerminalQuickCommands | undefined
runtimeEnvironments: PublicKnownRuntimeEnvironment[]
settings: GlobalSettings | null
}
const EMPTY_RUNTIME_ENVIRONMENTS: PublicKnownRuntimeEnvironment[] = []
const DISABLED_TERMINAL_QUICK_COMMAND_HOSTS: TerminalQuickCommandHost[] = []
const DISABLED_TERMINAL_QUICK_COMMAND_HOST_STATE: TerminalQuickCommandHostState = {
executionHostId: LOCAL_EXECUTION_HOST_ID,
loadRemote: null,
remoteConnectionGeneration: 0,
remoteEnvironmentId: null,
remoteHostId: null,
remoteState: undefined,
runtimeEnvironments: EMPTY_RUNTIME_ENVIRONMENTS,
settings: null
}
export function getHostedTerminalQuickCommandKey(
hostId: ExecutionHostId,
commandId: string
@@ -68,41 +97,59 @@ export function getTerminalQuickCommandHostOptions(
}).map((host) => ({ id: host.id, label: host.label }))
}
export function useTerminalQuickCommandHosts(worktreeId: string): {
export function useTerminalQuickCommandHosts(
worktreeId: string,
enabled = true
): {
executionHostId: ExecutionHostId
hosts: TerminalQuickCommandHost[]
refreshRemoteHost: () => void
remoteHostLoadFailed: boolean
remoteHostPending: boolean
} {
const executionHostId = useAppStore((state) => getExecutionHostIdForWorktree(state, worktreeId))
const settings = useAppStore((state) => state.settings)
const runtimeEnvironments = useAppStore((state) => state.runtimeEnvironments)
const remoteState = useAppStore((state) => {
const parsed = parseExecutionHostId(executionHostId)
return parsed?.kind === 'runtime'
? state.runtimeTerminalQuickCommands.get(parsed.environmentId)
: undefined
})
const loadRemote = useAppStore((state) => state.loadRuntimeTerminalQuickCommands)
const parsedExecutionHost = parseExecutionHostId(executionHostId)
const remoteHostId = parsedExecutionHost?.kind === 'runtime' ? parsedExecutionHost.id : null
const remoteEnvironmentId =
parsedExecutionHost?.kind === 'runtime' ? parsedExecutionHost.environmentId : null
const remoteConnectionGeneration = useAppStore((state) =>
remoteEnvironmentId
? (state.runtimeStatusByEnvironmentId.get(remoteEnvironmentId)?.connectionGeneration ?? 0)
: 0
const {
executionHostId,
loadRemote,
remoteConnectionGeneration,
remoteEnvironmentId,
remoteHostId,
remoteState,
runtimeEnvironments,
settings
} = useAppStore(
useShallow((state): TerminalQuickCommandHostState => {
if (!enabled) {
return DISABLED_TERMINAL_QUICK_COMMAND_HOST_STATE
}
const executionHostId = getExecutionHostIdForWorktree(state, worktreeId)
const parsedExecutionHost = parseExecutionHostId(executionHostId)
const remoteEnvironmentId =
parsedExecutionHost?.kind === 'runtime' ? parsedExecutionHost.environmentId : null
return {
executionHostId,
loadRemote: state.loadRuntimeTerminalQuickCommands,
remoteConnectionGeneration: remoteEnvironmentId
? (state.runtimeStatusByEnvironmentId.get(remoteEnvironmentId)?.connectionGeneration ?? 0)
: 0,
remoteEnvironmentId,
remoteHostId: parsedExecutionHost?.kind === 'runtime' ? parsedExecutionHost.id : null,
remoteState: remoteEnvironmentId
? state.runtimeTerminalQuickCommands.get(remoteEnvironmentId)
: undefined,
runtimeEnvironments: state.runtimeEnvironments,
settings: state.settings
}
})
)
useEffect(() => {
if (remoteEnvironmentId) {
if (loadRemote && remoteEnvironmentId) {
void loadRemote(remoteEnvironmentId)
}
}, [loadRemote, remoteConnectionGeneration, remoteEnvironmentId])
const refreshRemoteHost = useCallback((): void => {
if (remoteEnvironmentId) {
if (loadRemote && remoteEnvironmentId) {
void loadRemote(remoteEnvironmentId, { force: true })
}
}, [loadRemote, remoteEnvironmentId])
@@ -122,6 +169,9 @@ export function useTerminalQuickCommandHosts(worktreeId: string): {
)
const hosts = useMemo(() => {
if (!enabled) {
return DISABLED_TERMINAL_QUICK_COMMAND_HOSTS
}
const hostOptions = getTerminalQuickCommandHostOptions(settings, runtimeEnvironments)
const result: TerminalQuickCommandHost[] = [
{
@@ -146,6 +196,7 @@ export function useTerminalQuickCommandHosts(worktreeId: string): {
})
return result
}, [
enabled,
remoteConnectionGeneration,
remoteEnvironmentId,
remoteHostId,