diff --git a/apps/arc-web/app/routes/session-detail.tsx b/apps/arc-web/app/routes/session-detail.tsx index cde384876..9d050eb4f 100644 --- a/apps/arc-web/app/routes/session-detail.tsx +++ b/apps/arc-web/app/routes/session-detail.tsx @@ -3,6 +3,8 @@ import { Link, useParams } from "react-router"; import { ChevronRightIcon } from "@heroicons/react/20/solid"; import { ChatBubbleLeftIcon, + ClipboardDocumentIcon, + CheckIcon, PencilSquareIcon, UserIcon, WrenchScrewdriverIcon, @@ -22,7 +24,7 @@ interface ToolUse { } type Turn = - | { kind: "user"; content: string } + | { kind: "user"; content: string; date?: string } | { kind: "assistant"; content: string } | { kind: "tool"; tools: ToolUse[] }; @@ -45,6 +47,7 @@ const sessions: Record = { turns: [ { kind: "user", + date: "Feb 28", content: "Add rate limiting to the auth endpoints. We're getting hit with brute force attempts on /api/auth/login and /api/auth/register. Use a sliding window approach with Redis, 10 requests per minute per IP.", }, { @@ -110,6 +113,7 @@ const sessions: Record = { turns: [ { kind: "user", + date: "Feb 28", content: "The CLI crashes when parsing nested TOML config values like [database.connection]. Can you debug and fix this?", }, { @@ -158,7 +162,7 @@ const sessions: Record = { model: "Opus 4.6", time: "1d ago", turns: [ - { kind: "user", content: "Help me migrate our app from React Router v6 to v7. We're using createBrowserRouter with data loaders." }, + { kind: "user", date: "Feb 26", content: "Help me migrate our app from React Router v6 to v7. We're using createBrowserRouter with data loaders." }, { kind: "assistant", content: "I'll audit your current router setup and identify what needs to change for v7. Let me scan the codebase." }, { kind: "tool", @@ -181,7 +185,7 @@ function makeFallbackSession(id: string): Session { model: "Opus 4.6", time: "", turns: [ - { kind: "user", content: "Hello, let's get started." }, + { kind: "user", date: "Feb 28", content: "Hello, let's get started." }, { kind: "assistant", content: "Sure! What would you like to work on?" }, ], }; @@ -259,28 +263,65 @@ function ToolBlock({ tools }: { tools: ToolUse[] }) { ); } -function UserBlock({ content }: { content: string }) { +function CopyButton({ text }: { text: string }) { + const [copied, setCopied] = useState(false); + + function handleCopy() { + navigator.clipboard.writeText(text).then(() => { + setCopied(true); + setTimeout(() => setCopied(false), 2000); + }); + } + return ( -
-
- + + ); +} + +function UserBlock({ content, date }: { content: string; date?: string }) { + return ( +
+
+
+ +
+
+
{content}
+
-
-
{content}
+
+ + {date != null && {date}}
); } -function AssistantBlock({ content }: { content: string }) { +function AssistantBlock({ content, showCopy }: { content: string; showCopy: boolean }) { return ( -
-
- -
-
-
{content}
+
+
+
+ +
+
+
{content}
+
+ {showCopy && ( +
+ +
+ )}
); } @@ -351,9 +392,12 @@ export default function SessionDetail() { {session.turns.map((turn, i) => { switch (turn.kind) { case "user": - return ; - case "assistant": - return ; + return ; + case "assistant": { + const next = session.turns[i + 1]; + const showCopy = next?.kind !== "tool"; + return ; + } case "tool": return
; }