diff --git a/apps/desktop/src/app/artifacts/index.tsx b/apps/desktop/src/app/artifacts/index.tsx index 45219522c5..ba9697518a 100644 --- a/apps/desktop/src/app/artifacts/index.tsx +++ b/apps/desktop/src/app/artifacts/index.tsx @@ -2,7 +2,7 @@ import type * as React from 'react' import { useCallback, useEffect, useMemo, useState } from 'react' import { useNavigate } from 'react-router-dom' -import { ZoomableImage } from '@/components/assistant-ui/zoomable-image' +import { ZoomableImage } from '@/components/chat/zoomable-image' import { PageLoader } from '@/components/page-loader' import { Button } from '@/components/ui/button' import { CopyButton } from '@/components/ui/copy-button' @@ -786,9 +786,6 @@ function ArtifactImageCard({ artifact, failedImage, onImageError, onOpenChat }: ) } -const CELL_ACTION_CLASS = - 'flex h-full w-full min-w-0 items-center gap-2 px-2.5 py-1.5 text-left text-sm leading-snug font-medium text-foreground/90 no-underline transition-colors hover:text-foreground hover:underline' - // Single click target for any row cell. External URLs render as ; // local actions render as ) diff --git a/apps/desktop/src/app/chat/composer/index.tsx b/apps/desktop/src/app/chat/composer/index.tsx index 6265b3d2da..06959bddf4 100644 --- a/apps/desktop/src/app/chat/composer/index.tsx +++ b/apps/desktop/src/app/chat/composer/index.tsx @@ -50,9 +50,6 @@ import type { ChatBarProps } from './types' import { UrlDialog } from './url-dialog' import { VoiceActivity, VoicePlaybackActivity } from './voice-activity' -const COMPOSER_SHELL_CLASS = - 'group/composer absolute bottom-0 left-1/2 z-30 w-[min(var(--composer-width),calc(100%-2rem))] max-w-full -translate-x-1/2 rounded-2xl pt-2 pb-[var(--composer-shell-pad-block-end)]' - function extractClipboardImageBlobs(clipboard: DataTransfer): Blob[] { const blobs: Blob[] = [] const seen = new Set() @@ -111,21 +108,6 @@ function extractClipboardImageBlobs(clipboard: DataTransfer): Blob[] { const COMPOSER_STACK_BREAKPOINT_PX = 320 -const COMPOSER_SCROLLED_DIM_CLASS = - 'opacity-30 group-hover/composer:opacity-100 group-focus-within/composer:opacity-100' - -const COMPOSER_FROST_CLASS = cn( - 'pointer-events-none absolute inset-0 -z-10 rounded-[inherit]', - 'bg-[color-mix(in_srgb,var(--dt-card)_72%,transparent)]', - 'backdrop-blur-[0.75rem] backdrop-saturate-[1.12]', - '[-webkit-backdrop-filter:blur(0.75rem)_saturate(1.12)]', - 'transition-[background-color] duration-150 ease-out', - 'group-data-[thread-scrolled-up]/composer:bg-[color-mix(in_srgb,var(--dt-card)_48%,transparent)]', - 'group-focus-within/composer:bg-[var(--dt-card)]', - 'group-focus-within/composer:[backdrop-filter:none]', - 'group-focus-within/composer:[-webkit-backdrop-filter:none]' -) - const COMPOSER_GLASS = { fadeBackground: 'linear-gradient(to bottom, transparent, color-mix(in srgb, var(--dt-background) 10%, transparent))', liquidKey: ['standard', '0.950', '0.072', '0', '46', '0.00', '128'].join(':'), @@ -921,7 +903,7 @@ export function ChatBar({ <> -
+
{dragActive && (
@@ -1042,11 +1041,27 @@ export function ChatBar({ export function ChatBarFallback() { return (
-
+
) diff --git a/apps/desktop/src/app/chat/sidebar/session-actions-menu.tsx b/apps/desktop/src/app/chat/sidebar/session-actions-menu.tsx index d5217748a3..5c58e1b10f 100644 --- a/apps/desktop/src/app/chat/sidebar/session-actions-menu.tsx +++ b/apps/desktop/src/app/chat/sidebar/session-actions-menu.tsx @@ -50,7 +50,6 @@ export function SessionActionsMenu({ align = 'end', sideOffset = 6 }: SessionActionsMenuProps) { - const itemClass = 'gap-2.5 text-foreground focus:bg-accent [&_svg]:size-4' const [renameOpen, setRenameOpen] = useState(false) return ( @@ -59,7 +58,7 @@ export function SessionActionsMenu({ {children} { triggerHaptic('selection') @@ -71,14 +70,14 @@ export function SessionActionsMenu({ { triggerHaptic('selection') @@ -89,7 +88,7 @@ export function SessionActionsMenu({ Export { triggerHaptic('selection') @@ -101,7 +100,10 @@ export function SessionActionsMenu({ { triggerHaptic('warning') diff --git a/apps/desktop/src/app/session/hooks/use-message-stream.ts b/apps/desktop/src/app/session/hooks/use-message-stream.ts index 5f0e52ee62..54cefc1be2 100644 --- a/apps/desktop/src/app/session/hooks/use-message-stream.ts +++ b/apps/desktop/src/app/session/hooks/use-message-stream.ts @@ -62,6 +62,15 @@ interface QueuedStreamDeltas { const STREAM_DELTA_FLUSH_MS = 16 +// Anonymous progress events that carry todos but no name still belong to the +// todo stream; named todo events are obviously routed there too. +function toTodoPayload(payload: GatewayEventPayload | undefined): GatewayEventPayload | undefined { + if (!payload) {return undefined} + const isTodo = payload.name === 'todo' || (!payload.name && Object.hasOwn(payload, 'todos')) + + return isTodo ? { ...payload, name: 'todo', tool_id: payload.tool_id || 'todo-live' } : undefined +} + export function useMessageStream({ activeSessionIdRef, hydrateFromStoredSession, @@ -552,17 +561,13 @@ export function useMessageStream({ setCurrentUsage(current => ({ ...current, ...payload.usage })) } } else if (event.type === 'tool.start' || event.type === 'tool.progress' || event.type === 'tool.generating') { - if (!sessionId) { - return - } - + if (!sessionId) {return} flushQueuedDeltas(sessionId) - - upsertToolCall(sessionId, payload, 'running') + upsertToolCall(sessionId, toTodoPayload(payload) ?? payload, 'running') } else if (event.type === 'tool.complete') { if (sessionId) { flushQueuedDeltas(sessionId) - upsertToolCall(sessionId, payload, 'complete') + upsertToolCall(sessionId, toTodoPayload(payload) ?? payload, 'complete') } if (typeof payload?.inline_diff === 'string' && payload.inline_diff.trim()) { diff --git a/apps/desktop/src/app/shell/statusbar-controls.tsx b/apps/desktop/src/app/shell/statusbar-controls.tsx index 0c426e2379..6ffad250e1 100644 --- a/apps/desktop/src/app/shell/statusbar-controls.tsx +++ b/apps/desktop/src/app/shell/statusbar-controls.tsx @@ -43,9 +43,6 @@ interface StatusbarControlsProps extends ComponentProps<'footer'> { items?: readonly StatusbarItem[] } -const statusbarItemClass = - 'inline-flex h-full cursor-pointer items-center gap-1 rounded-none px-1.5 text-[0.68rem] text-muted-foreground/95 transition-colors hover:bg-(--chrome-action-hover) hover:text-foreground disabled:cursor-default disabled:opacity-45' - export function StatusbarControls({ className, leftItems = [], items = [], ...props }: StatusbarControlsProps) { const navigate = useNavigate() @@ -91,7 +88,10 @@ function StatusbarItemView({ item, navigate }: { item: StatusbarItem; navigate: