perf(renderer): lazy load Linear setup dialog (#11687)

This commit is contained in:
Neil 2026-07-31 00:25:52 -07:00 committed by GitHub
parent e467b3ff7b
commit 11936f08ab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 93 additions and 70 deletions

View File

@ -328,6 +328,18 @@ describe('renderer startup runtime routing', () => {
)
})
it('loads Linear agent setup implementation only after the prompt opens it', () => {
const source = readFileSync(
join(process.cwd(), 'src/renderer/src/components/sidebar/LinearAgentSkillSetupPrompt.tsx'),
'utf8'
)
expect(source).toContain("() => import('./LinearAgentSkillSetupDialog')")
expect(source).not.toContain("from './LinearAgentSkillSetupDialog'")
expect(source).toContain('const setupDialog = setupDialogOpen ? (')
expect(source).toContain('<Suspense fallback={null}>')
})
it('does not eagerly import optional status-bar segments on startup', () => {
const source = readFileSync(
join(process.cwd(), 'src/renderer/src/components/status-bar/StatusBar.tsx'),

View File

@ -191,3 +191,5 @@ export function LinearAgentSkillSetupDialog({
</Dialog>
)
}
export default LinearAgentSkillSetupDialog

View File

@ -119,6 +119,7 @@ async function renderPrompt(
await act(async () => {
root?.render(<LinearAgentSkillSetupPrompt {...props} />)
})
await import('./LinearAgentSkillSetupDialog')
await act(async () => {})
}

View File

@ -147,6 +147,9 @@ async function renderPrompt(
await act(async () => {
root?.render(<LinearAgentSkillSetupPrompt {...props} />)
})
if (props.surface === 'modal') {
await import('./LinearAgentSkillSetupDialog')
}
await act(async () => {})
return container
}
@ -178,6 +181,7 @@ function findBodyButton(label: string): HTMLButtonElement | undefined {
}
async function settleRender(): Promise<void> {
await import('./LinearAgentSkillSetupDialog')
await act(async () => {})
await act(async () => {})
}
@ -253,12 +257,7 @@ describe('LinearAgentSkillSetupPrompt', () => {
const unlinked = await renderPrompt({ linked: false, remote: false })
expect(unlinked.textContent).not.toContain('Set up Linear agent skill')
await act(async () => {
root?.unmount()
})
root = null
unlinked.remove()
container = null
await unmountPrompt()
const ready = await renderPrompt({ linked: true, remote: false })
expect(ready.textContent).not.toContain('Set up Linear agent skill')
@ -343,6 +342,7 @@ describe('LinearAgentSkillSetupPrompt', () => {
await act(async () => {
setupButton?.dispatchEvent(new MouseEvent('click', { bubbles: true }))
})
await settleRender()
expect(document.body.textContent).toContain("wsl.exe -d 'Fedora' -- bash -lc 'npx skills add")
expect(mocks.panelProps.at(-1)).toEqual(
@ -425,7 +425,7 @@ describe('LinearAgentSkillSetupPrompt', () => {
expect(mocks.getWslCliStatus).not.toHaveBeenCalled()
})
it('opens the terminal setup panel in a dialog only after the user asks to set up', async () => {
it('keeps the prompt usable and loads the lazy setup dialog only when requested', async () => {
const rendered = await renderPrompt({ linked: true, remote: false })
expect(document.body.querySelector('[data-testid="linear-skill-inline-panel"]')).toBeNull()
@ -436,6 +436,7 @@ describe('LinearAgentSkillSetupPrompt', () => {
await act(async () => {
setupButton?.dispatchEvent(new MouseEvent('click', { bubbles: true }))
})
await settleRender()
expect(document.body.querySelector('[data-testid="linear-skill-inline-panel"]')).not.toBeNull()
expect(document.body.textContent).toContain('orca-linear')

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { Suspense, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { RefreshCw, TicketCheck, X } from 'lucide-react'
import type { CliInstallStatus } from '../../../../shared/cli-install-types'
import type { ProjectExecutionRuntimeResolution } from '../../../../shared/project-execution-runtime'
@ -16,6 +16,7 @@ import {
ensureOrcaCliAvailableForAgentSkillTerminal,
isOrcaCliAvailableOnPath
} from '@/lib/agent-skill-cli-prerequisite'
import { lazyWithRetry } from '@/lib/lazy-with-retry'
import { cn } from '@/lib/utils'
import {
buildSkillCommandForRuntime,
@ -45,9 +46,12 @@ import {
readLocalDismissed,
type LinearAgentSkillPromptSettings
} from './linear-agent-skill-runtime'
import { LinearAgentSkillSetupDialog } from './LinearAgentSkillSetupDialog'
import { translate } from '@/i18n/i18n'
const LinearAgentSkillSetupDialog = lazyWithRetry(() => import('./LinearAgentSkillSetupDialog'), {
reloadKey: 'linear-agent-skill-setup-dialog'
})
export const _linearAgentSkillSetupPromptInternalsForTests = {
resetSessionReminders(): void {
resetLinearAgentSkillSetupReminderToastState()
@ -278,69 +282,71 @@ export function LinearAgentSkillSetupPrompt({
return null
}
const setupDialog = (
<LinearAgentSkillSetupDialog
open={setupDialogOpen}
showSuccess={showSuccessModal}
successDescription={successDescription}
missingLabel={missingLabel}
command={command}
installedCommand={installedCommand}
terminalShellOverride={terminalShellOverride}
installed={skill.installed}
loading={showCheckingModal || cliLoading || skill.loading}
error={skill.error}
getPrerequisiteStatus={
agentRuntime.runtime === 'wsl'
? () => window.api.cli.getWslInstallStatus(getWslCliDistroRequest(agentRuntime))
: undefined
}
onBeforeOpenTerminal={async () => {
const requestIdentity = setupCheckIdentity
const writeIfCurrent = (write: () => void): void => {
writeCliStatusForIdentity(requestIdentity, write)
}
const nextStatus =
const setupDialog = setupDialogOpen ? (
<Suspense fallback={null}>
<LinearAgentSkillSetupDialog
open
showSuccess={showSuccessModal}
successDescription={successDescription}
missingLabel={missingLabel}
command={command}
installedCommand={installedCommand}
terminalShellOverride={terminalShellOverride}
installed={skill.installed}
loading={showCheckingModal || cliLoading || skill.loading}
error={skill.error}
getPrerequisiteStatus={
agentRuntime.runtime === 'wsl'
? await ensureWslCliAvailableForAgentSkillTerminal(agentRuntime)
: await ensureOrcaCliAvailableForAgentSkillTerminal({
onStatusChange: (nextCliStatus) => {
writeIfCurrent(() => setCliStatus(nextCliStatus))
}
})
if (agentRuntime.runtime === 'wsl') {
writeIfCurrent(() => setCliStatus(nextStatus))
? () => window.api.cli.getWslInstallStatus(getWslCliDistroRequest(agentRuntime))
: undefined
}
}}
onRecheck={async () => {
if (surface === 'modal') {
setActiveSetupCheckIdentity(setupCheckIdentity)
setSetupCheckResult('checking')
await Promise.all([refreshCliStatus(), skill.refresh()])
return
}
await refreshCliStatus()
await skill.refresh()
}}
onOpenChange={(open) => {
if (open) {
setSetupDialogOpen(true)
return
}
if (showSuccessModal) {
closeSuccessModal()
return
}
if (surface === 'modal') {
snoozeForSession()
return
}
setSetupDialogOpen(false)
}}
onDismissPermanently={dismissPermanently}
onDone={closeSuccessModal}
/>
)
onBeforeOpenTerminal={async () => {
const requestIdentity = setupCheckIdentity
const writeIfCurrent = (write: () => void): void => {
writeCliStatusForIdentity(requestIdentity, write)
}
const nextStatus =
agentRuntime.runtime === 'wsl'
? await ensureWslCliAvailableForAgentSkillTerminal(agentRuntime)
: await ensureOrcaCliAvailableForAgentSkillTerminal({
onStatusChange: (nextCliStatus) => {
writeIfCurrent(() => setCliStatus(nextCliStatus))
}
})
if (agentRuntime.runtime === 'wsl') {
writeIfCurrent(() => setCliStatus(nextStatus))
}
}}
onRecheck={async () => {
if (surface === 'modal') {
setActiveSetupCheckIdentity(setupCheckIdentity)
setSetupCheckResult('checking')
await Promise.all([refreshCliStatus(), skill.refresh()])
return
}
await refreshCliStatus()
await skill.refresh()
}}
onOpenChange={(open) => {
if (open) {
setSetupDialogOpen(true)
return
}
if (showSuccessModal) {
closeSuccessModal()
return
}
if (surface === 'modal') {
snoozeForSession()
return
}
setSetupDialogOpen(false)
}}
onDismissPermanently={dismissPermanently}
onDone={closeSuccessModal}
/>
</Suspense>
) : null
if (surface === 'modal') {
return setupDialog

View File

@ -107,6 +107,7 @@ async function renderPrompt(
<LinearAgentSkillSetupPrompt linked={true} remote={false} surface="modal" {...props} />
)
})
await import('./LinearAgentSkillSetupDialog')
await act(async () => {})
}