diff --git a/frontend/src/components/assistant/ChatSidebar.tsx b/frontend/src/components/assistant/ChatSidebar.tsx
index 133f0a60..bea51f18 100644
--- a/frontend/src/components/assistant/ChatSidebar.tsx
+++ b/frontend/src/components/assistant/ChatSidebar.tsx
@@ -1,3 +1,4 @@
+import { useState } from 'react'
import { Plus, Pin, Trash2, MessageSquare, History, X } from 'lucide-react'
import { cn } from '@/lib/utils'
import type { ChatListItem } from '@/types/assistant-chat'
@@ -84,7 +85,7 @@ export function ChatSidebar({
{pinnedChats.length > 0 && (
-
+
Pinned
@@ -184,39 +185,65 @@ function ChatItem({
onDelete: () => void
onTogglePin: () => void
}) {
+ const [confirming, setConfirming] = useState(false)
+
return (
-
{chat.title}
-
- {chat.message_count} messages
+ {confirming ? (
+
+ Delete?
+
+
+
+ ) : (
+ <>
+
{chat.title}
+
+ {chat.message_count} messages
+
+ >
+ )}
+
+ {!confirming && (
+
+
+
-
-
-
-
-
+ )}
)
}
diff --git a/frontend/src/components/assistant/TaskLane.tsx b/frontend/src/components/assistant/TaskLane.tsx
index 7a6a5850..590f34b3 100644
--- a/frontend/src/components/assistant/TaskLane.tsx
+++ b/frontend/src/components/assistant/TaskLane.tsx
@@ -225,8 +225,8 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa
return (
{/* Resize grip handle */}
-
-
-
-
-
-
+ {Array.from({ length: 6 }).map((_, i) => (
+
+ ))}
{/* Header */}
-
+
Tasks
0 && (
-
+
Questions
@@ -282,16 +279,19 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa
if (q.state === 'done') {
return (
-
updateTask(idx, { state: 'active' })}>
-
{q.text}
-
"{q.value}"
+
updateTask(idx, { state: 'active' })}>
+
+
+ {q.text}
+
+
"{q.value}"
)
}
if (q.state === 'skipped') {
return (
-
+
updateTask(idx, { state: 'pending' })} title="Click to restore">
{q.text}
Skipped
@@ -342,9 +342,10 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa
)}
@@ -357,7 +358,7 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa
{/* ── Checks Section ── */}
{actionTasks.length > 0 && (
-
+
Diagnostic Checks
@@ -401,10 +402,10 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa
if (a.state === 'done') {
return (
-
updateTask(idx, { state: 'active' })}>
-
-
{a.label}
-
✓ Done
+
updateTask(idx, { state: 'active' })}>
+
+
+ {a.label}
)
@@ -412,7 +413,7 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa
if (a.state === 'skipped') {
return (
-
+
updateTask(idx, { state: 'pending' })} title="Click to restore">
{a.label}
Skipped
@@ -464,24 +465,19 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa
) : (
-
+
-
)}
@@ -495,19 +491,24 @@ export function TaskLane({ questions, actions, sessionId, onSubmit, onClose, loa
{/* Footer */}
{/* Progress bar */}
-
- {tasks.map((t, i) => (
-
- ))}
+
+
+ {tasks.map((t, i) => (
+
+ ))}
+
+
+ {handledCount}/{totalCount}
+
{/* Collapsible preview */}
{anyHandled && (
diff --git a/frontend/src/index.css b/frontend/src/index.css
index 2fb1f923..8405b22f 100644
--- a/frontend/src/index.css
+++ b/frontend/src/index.css
@@ -82,6 +82,7 @@
--animate-fade-in: fade-in 200ms ease-out both;
--animate-fade-in-up: fade-in-up 200ms ease-out both;
--animate-slide-in-left: slide-in-from-left 200ms ease-out;
+ --animate-slide-in-right: slide-in-from-right 200ms ease-out both;
--animate-slide-in-bottom: slide-in-from-bottom 200ms ease-out both;
--animate-scale-in: scale-in 150ms ease-out both;
--animate-fade: fadeIn 300ms ease both;
@@ -95,6 +96,9 @@
@keyframes slide-in-from-left {
from { transform: translateX(-100%); } to { transform: translateX(0); }
}
+ @keyframes slide-in-from-right {
+ from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: translateX(0); }
+ }
@keyframes slide-in-from-bottom {
from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: translateY(0); }
}