From c52297dd93aeb6ecaef46a1a803467854a9dc19e Mon Sep 17 00:00:00 2001 From: Merge Sim Date: Wed, 2 Sep 2026 14:12:16 -0700 Subject: [PATCH] fix(native-chat): make structured launches observable and recoverable --- .../components/tab-bar/QuickLaunchButton.tsx | 22 +++++++-- .../components/tab-bar/TabBarCreateEntry.tsx | 24 ++++++++- .../tab-bar/TabBarCreateEntryRow.tsx | 13 +++-- ...launch-agent-structured-chat-guard.test.ts | 6 +++ .../structured-agent-session-launch.test.ts | 13 ++++- .../lib/structured-agent-session-launch.ts | 49 +++++++++++++++++++ 6 files changed, 116 insertions(+), 11 deletions(-) diff --git a/src/renderer/src/components/tab-bar/QuickLaunchButton.tsx b/src/renderer/src/components/tab-bar/QuickLaunchButton.tsx index 6af2508048c..85d978e3bf6 100644 --- a/src/renderer/src/components/tab-bar/QuickLaunchButton.tsx +++ b/src/renderer/src/components/tab-bar/QuickLaunchButton.tsx @@ -1,5 +1,5 @@ import React, { useCallback } from 'react' -import { Settings as SettingsIcon } from 'lucide-react' +import { Loader2, Settings as SettingsIcon } from 'lucide-react' import { toast } from 'sonner' import { DropdownMenuItem, DropdownMenuShortcut } from '@/components/ui/dropdown-menu' import { getAgentCatalog, AgentIcon } from '@/lib/agent-catalog' @@ -15,6 +15,7 @@ import { filterEnabledTuiAgents } from '../../../../shared/tui-agent-selection' import { translate } from '@/i18n/i18n' +import { useStructuredCodexLaunchStatus } from '@/lib/structured-agent-session-launch' export type QuickLaunchAgentMenuItemsProps = { worktreeId: string @@ -116,6 +117,7 @@ function QuickLaunchAgentMenuItemsInner({ const openSettingsPage = useAppStore((s) => s.openSettingsPage) const openSettingsTarget = useAppStore((s) => s.openSettingsTarget) const newAgentShortcut = useOptionalShortcutLabel('tab.newAgent') + const structuredCodexLaunchStatus = useStructuredCodexLaunchStatus(worktreeId) const openAgentSettings = useCallback(() => { openSettingsTarget({ pane: 'agents', repoId: null }) @@ -197,21 +199,31 @@ function QuickLaunchAgentMenuItemsInner({ {agents.map((agent) => { const entry = getCatalogEntry(agent) const label = entry?.label ?? agent + const isStructuredCodexPending = + agent === 'codex' && structuredCodexLaunchStatus === 'pending' + const menuLabel = isStructuredCodexPending ? 'Starting Codex chat…' : label const showsDefaultAgentShortcut = newAgentShortcut !== null && defaultAgent !== 'blank' && agent === defaultAgent return ( runLaunch(agent)} className="gap-2 rounded-[7px] px-2 py-1.5 text-[12px] leading-5 font-medium" title={translate( 'auto.components.tab.bar.QuickLaunchButton.ec2adf093e', - 'Launch {{value0}} in a new terminal', - { value0: label } + isStructuredCodexPending + ? 'Starting Codex chat…' + : 'Launch {{value0}} in a new terminal', + isStructuredCodexPending ? undefined : { value0: label } )} > - - {label} + {isStructuredCodexPending ? ( +