feat: add operational timeline workspace

This commit is contained in:
2026-08-19 16:42:41 +08:00
parent d2f2895c36
commit 45f1ebee7e
19 changed files with 1127 additions and 105 deletions
@@ -1,6 +1,7 @@
import {
Activity,
CheckCircle2,
Clock3,
ChevronsUpDown,
ChevronLeft,
DatabaseZap,
@@ -82,6 +83,13 @@ import type {
export type AgentCommandPanelPresentation = "desktop-dock" | "desktop-floating" | "mobile-sheet";
export type AgentWorkspaceContextItem = {
id: string;
label: string;
value: string;
tone?: "neutral" | "info" | "warning";
};
type AgentCommandPanelProps = {
presentation?: AgentCommandPanelPresentation;
collapsing?: boolean;
@@ -99,6 +107,7 @@ type AgentCommandPanelProps = {
selectedModel?: string;
approvalMode?: AgentApprovalMode;
uiResults?: AgentUiResult[];
workspaceContext?: AgentWorkspaceContextItem[];
onCollapse: () => void;
onRefreshHistory?: () => Promise<void> | void;
onStartNewSession?: () => Promise<void> | void;
@@ -150,6 +159,7 @@ export function AgentCommandPanel({
selectedModel = "",
approvalMode = "request",
uiResults = [],
workspaceContext = [],
onCollapse,
onRefreshHistory,
onStartNewSession,
@@ -302,7 +312,7 @@ export function AgentCommandPanel({
"pointer-events-auto flex h-full min-h-0 w-full flex-col",
"agent-panel-shell",
presentation === "desktop-dock"
? "acrylic-panel overflow-hidden rounded-r-2xl border-y border-r"
? "surface-dock overflow-hidden rounded-r-2xl border-y border-r shadow-[0_12px_32px_rgba(15,23,42,0.12)]"
: desktopFloating
? "acrylic-panel overflow-visible rounded-2xl border"
: "overflow-hidden rounded-none border-0 bg-transparent",
@@ -423,6 +433,27 @@ export function AgentCommandPanel({
</header>
</div>
{workspaceContext.length > 0 ? (
<div className="mx-3 mb-2 flex shrink-0 items-center gap-2 overflow-x-auto rounded-lg bg-slate-900/[0.045] px-2.5 py-2 text-[10px] text-slate-500">
<Clock3 size={13} className="shrink-0 text-blue-600" aria-hidden="true" />
<span className="shrink-0 font-semibold uppercase tracking-[0.12em] text-slate-500"></span>
{workspaceContext.map((item) => (
<span
key={item.id}
className={cn(
"shrink-0 rounded-md px-2 py-1",
item.tone === "info" && "bg-blue-50 text-blue-700",
item.tone === "warning" && "bg-amber-50 text-amber-700",
(!item.tone || item.tone === "neutral") && "bg-white/70 text-slate-600"
)}
title={`${item.label}${item.value}`}
>
{item.label} · <strong className="font-semibold">{item.value}</strong>
</span>
))}
</div>
) : null}
{floatingPresentation ? (
<AnimatePresence initial={false}>
{hasConversation && !historyOpen ? (