fix(dashboard): preserve inspector input and state

This commit is contained in:
Brennan Benson
2026-08-09 17:35:54 -07:00
parent d6e1b9958b
commit fd28b89b00
5 changed files with 48 additions and 4 deletions
@@ -149,6 +149,32 @@ describe('AgentChatPanel', () => {
expect(screen.getByLabelText('Reply to this agent')).toHaveValue('hello')
})
it.each([
['an active composition', { isComposing: true }],
['the legacy IME key code', { keyCode: 229 }]
])('does not submit the Enter that confirms %s', (_label, keyboardInit) => {
render(<AgentChatPanel card={card()} onClose={vi.fn()} />)
const input = screen.getByLabelText('Reply to this agent')
fireEvent.change(input, { target: { value: 'unfinished conversion' } })
fireEvent.keyDown(input, { key: 'Enter', ...keyboardInit })
expect(terminalInput).not.toHaveBeenCalled()
expect(input).toHaveValue('unfinished conversion')
})
it('shows acknowledged completions with the dashboard idle state', () => {
render(
<AgentChatPanel
card={card({ bucket: 'idle', dotState: 'done', unseen: false })}
onClose={vi.fn()}
/>
)
expect(screen.getByLabelText('Idle')).toBeInTheDocument()
expect(screen.queryByLabelText('Done')).not.toBeInTheDocument()
})
it('withholds the composer when the agent has no live pane', () => {
render(<AgentChatPanel card={card({ ptyId: null })} onClose={vi.fn()} />)
@@ -15,8 +15,12 @@ import { selectNativeChatViewState } from '@/components/native-chat/native-chat-
import { NATIVE_CHAT_SUBMIT_DELAY_MS } from '../../../../shared/native-chat-answer-stepping'
import { translate } from '@/i18n/i18n'
import { formatAgentTypeLabel } from '@/lib/agent-status'
import { isImeCompositionKeyDown } from '@/lib/ime-composition-keyboard-event'
import { cn } from '@/lib/utils'
import type { DashboardCard } from '../../../../shared/dashboard-snapshot'
import {
dashboardCardDisplayState,
type DashboardCard
} from '../../../../shared/dashboard-snapshot'
import { resolveAgentChatPanelMode, type AgentChatPanelMode } from './agent-chat-panel-mode'
type AgentChatPanelProps = {
@@ -183,7 +187,7 @@ function AgentChatComposer({ card }: { card: DashboardCard }): React.JSX.Element
setFailedSend(null)
}}
onKeyDown={(event) => {
if (event.key === 'Enter' && !event.shiftKey) {
if (event.key === 'Enter' && !event.shiftKey && !isImeCompositionKeyDown(event)) {
event.preventDefault()
void send()
}
@@ -260,7 +264,7 @@ export function AgentChatPanel({
)}
>
<header className="flex shrink-0 items-start gap-2 border-b border-border px-3 py-2.5">
<AgentStateDot state={card.dotState} size="md" className="mt-0.5" />
<AgentStateDot state={dashboardCardDisplayState(card)} size="md" className="mt-0.5" />
<span className="min-w-0 flex-1">
<h2 id={titleId} className="truncate text-[12px] leading-normal font-semibold">
{agentName(card)}
@@ -337,6 +337,19 @@ describe('AgentKanbanCard', () => {
fireEvent.click(screen.getByText('Review the change'))
expect(onOpenTerminal).toHaveBeenLastCalledWith(windowsCard)
const ctrlEnterCard = {
...windowsCard,
terminalInput: { ...windowsCard.terminalInput, ctrlEnterCsiU: true }
}
rerender(
<TooltipProvider>
<AgentKanbanCard card={ctrlEnterCard} now={2_000} onOpenTerminal={onOpenTerminal} />
</TooltipProvider>
)
fireEvent.click(screen.getByText('Review the change'))
expect(onOpenTerminal).toHaveBeenLastCalledWith(ctrlEnterCard)
})
it('updates the relative age when the UI language changes', async () => {
@@ -91,6 +91,7 @@ function sameTerminalInput(
a.localWindowsConpty === b.localWindowsConpty &&
a.osRelease === b.osRelease &&
a.windowsShiftEnterEncoding === b.windowsShiftEnterEncoding &&
a.ctrlEnterCsiU === b.ctrlEnterCsiU &&
a.kittyKeyboardAdvertised === b.kittyKeyboardAdvertised)
)
}
+1 -1
View File
@@ -104,7 +104,7 @@ export type DashboardCard = {
/** Optional for preload compatibility with snapshots produced before Agent Map.
* Also keeps the inspector from reading remote transcript paths locally. */
hostKind?: DashboardCardHostKind
/** Effective renderer mode for this agent's terminal tab. */
/** Initial dashboard inspector mode derived from the user's Chat UI default. */
viewMode?: DashboardCardViewMode
/** Exact owner used by in-window workspace actions when IDs collide across hosts. */
executionHostId?: ExecutionHostId