feat(web): workspace components — ComparePane, Memory page, McpDialog, error boundaries, message-parts
- Add ComparePane.tsx: side-by-side AI response comparison - Add Memory.tsx: memory management page with CRUD UI - Add McpPermissionDialog.tsx: MCP tool permission approval dialog - Add McpResponseDisplay.tsx: MCP response visualization - Add MessageBoundary.tsx + MessageListErrorBoundary.tsx: error resilience - Add EmptyState.tsx: contextual empty state component - Add KeyboardShortcutsDialog.tsx: keyboard shortcut reference - Add message-parts/: ActionRow, CompactCard, MistakeRecoverySentinel, ReasoningBlock, SendToTerminalMenu, StatsLine, SummaryCard - Add useDraftPersistence.ts: draft message persistence hook - Add useTerminals.ts: terminal session management hook - Add keyboard-shortcuts.ts + tool-utils.ts: shared utilities - Extend components: ChatInput, MessageBubble, MessageList, Workspace, panes - Extend hooks: useTerminalSocket, useSessionStream test suite - Update pages: Home, Project — workspace layout and session flow
This commit is contained in:
@@ -13,7 +13,7 @@ import { useViewport } from '@/hooks/useViewport';
|
||||
import { formatModelLabel } from '@/lib/model-label';
|
||||
|
||||
interface Props {
|
||||
value: string;
|
||||
value: string | null;
|
||||
onChange: (model: string) => void | Promise<void>;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ function ModelList({
|
||||
}: {
|
||||
models: ModelInfo[] | null;
|
||||
error: string | null;
|
||||
value: string;
|
||||
value: string | null;
|
||||
onPick: (id: string) => void;
|
||||
}) {
|
||||
if (error) {
|
||||
@@ -82,8 +82,8 @@ export function ModelPicker({ value, onChange }: Props) {
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setOpen(true)}
|
||||
aria-label={`Model: ${value}`}
|
||||
title={value}
|
||||
aria-label={`Model: ${value ?? 'default'}`}
|
||||
title={value ?? undefined}
|
||||
className="inline-flex items-center justify-center min-h-[36px] min-w-[44px] rounded text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
<Cpu className="size-4" />
|
||||
@@ -104,7 +104,7 @@ export function ModelPicker({ value, onChange }: Props) {
|
||||
type="button"
|
||||
className="text-xs font-mono text-muted-foreground hover:text-foreground flex items-center gap-1 px-1.5 py-0.5 rounded hover:bg-muted/60"
|
||||
>
|
||||
{formatModelLabel(value)}
|
||||
{value ? formatModelLabel(value) : 'Model'}
|
||||
<ChevronDown className="size-3 opacity-70" />
|
||||
</button>
|
||||
</DropdownMenuTrigger>
|
||||
|
||||
Reference in New Issue
Block a user