Auto-refresh active sessions, collapsible skill categories, platform toolsets in config, search highlighting

This commit is contained in:
Hermes
2026-04-09 21:38:33 -05:00
parent d86cbea6a5
commit 61e512ffe5
4 changed files with 83 additions and 20 deletions
+11 -1
View File
@@ -1,6 +1,6 @@
"use client";
import { use, useState, useRef } from "react";
import { use, useState, useRef, useEffect } from "react";
import { ArrowLeft, Send, Loader2, Eye, RefreshCw, Trash2 } from "lucide-react";
import Link from "next/link";
import { useSession, useMessages } from "@/lib/hooks";
@@ -37,6 +37,16 @@ export default function SessionReplayPage({ params }: { params: Promise<{ id: st
const session = sessionData?.session;
const messages = messagesData?.items || [];
// Auto-refresh active sessions every 5s
useEffect(() => {
if (!session || session.ended_at) return;
const interval = setInterval(() => {
qc.invalidateQueries({ queryKey: ["messages", id, msgLimit] });
qc.invalidateQueries({ queryKey: ["session", id] });
}, 5000);
return () => clearInterval(interval);
}, [session, id, msgLimit, qc]);
// Filter based on verbosity
let visibleMessages = messages.filter((m) => {
if (m.role === "user") return true;
+11 -1
View File
@@ -14,6 +14,12 @@ const PLATFORMS = [
{ id: "web", label: "Web" },
] as const;
function highlightMatch(text: string, query: string): string {
if (!query) return text;
const escaped = query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
return text.replace(new RegExp("(" + escaped + ")", "gi"), '<mark style="background:var(--accent-dim);color:var(--accent);border-radius:2px;padding:0 2px">$1</mark>');
}
export default function HistoryPage() {
const [filter, setFilter] = useState<string | null>(null);
const [query, setQuery] = useState("");
@@ -68,7 +74,11 @@ export default function HistoryPage() {
<div className="text-[12px] mb-0.5" style={{ color: "var(--text-2)" }}>
{r.session_title || r.session_id.slice(0, 8)}
</div>
<p className="text-[13px] line-clamp-2" style={{ color: "var(--text-1)" }}>{r.content}</p>
<p className="text-[13px] line-clamp-2" style={{ color: "var(--text-1)" }}
dangerouslySetInnerHTML={{
__html: highlightMatch(r.content, query),
}}
/>
</div>
</a>
))}