From e24c179e89e2d2b3ef0330566c282449ea779933 Mon Sep 17 00:00:00 2001 From: Hermes Date: Thu, 9 Apr 2026 21:25:10 -0500 Subject: [PATCH] Markdown rendering for skills, refresh button on replay - react-markdown + remark-gfm for proper skill SKILL.md rendering - Prose styles matching dark theme (tables, code blocks, blockquotes) - Strips YAML frontmatter before rendering - Refresh button in session replay header --- app/globals.css | 35 + app/history/[id]/page.tsx | 10 +- app/skills/[name]/page.tsx | 14 +- components/Markdown.tsx | 12 + package-lock.json | 1476 +++++++++++++++++++++++++++++++++++- package.json | 4 +- 6 files changed, 1539 insertions(+), 12 deletions(-) create mode 100644 components/Markdown.tsx diff --git a/app/globals.css b/app/globals.css index 87020c4..da05eae 100644 --- a/app/globals.css +++ b/app/globals.css @@ -68,6 +68,41 @@ body { .btn-accent:active { opacity: 0.7; } .btn-accent:disabled { opacity: 0.3; } +/* Markdown prose */ +.prose-hermes { + font-size: 13px; + line-height: 1.7; + color: var(--text-1); +} +.prose-hermes h1 { font-size: 18px; font-weight: 700; margin: 20px 0 8px; color: var(--text-1); } +.prose-hermes h2 { font-size: 16px; font-weight: 600; margin: 16px 0 6px; color: var(--text-1); } +.prose-hermes h3 { font-size: 14px; font-weight: 600; margin: 12px 0 4px; color: var(--text-1); } +.prose-hermes p { margin: 6px 0; } +.prose-hermes ul, .prose-hermes ol { margin: 6px 0; padding-left: 20px; } +.prose-hermes li { margin: 2px 0; } +.prose-hermes code { + font-size: 12px; + background: rgba(255,255,255,0.06); + padding: 1px 5px; + border-radius: 4px; + font-family: ui-monospace, "SF Mono", monospace; +} +.prose-hermes pre { + background: rgba(0,0,0,0.3); + border-radius: 8px; + padding: 12px; + overflow-x: auto; + margin: 8px 0; +} +.prose-hermes pre code { background: none; padding: 0; } +.prose-hermes a { color: var(--accent); text-decoration: none; } +.prose-hermes table { width: 100%; border-collapse: collapse; margin: 8px 0; font-size: 12px; } +.prose-hermes th { text-align: left; padding: 6px 8px; border-bottom: 1px solid var(--border); color: var(--text-2); font-weight: 600; } +.prose-hermes td { padding: 6px 8px; border-bottom: 1px solid var(--border); } +.prose-hermes blockquote { border-left: 3px solid var(--accent); padding-left: 12px; margin: 8px 0; color: var(--text-2); } +.prose-hermes hr { border: none; border-top: 1px solid var(--border); margin: 16px 0; } +.prose-hermes strong { color: var(--text-1); } + /* Divider */ .divider { height: 1px; diff --git a/app/history/[id]/page.tsx b/app/history/[id]/page.tsx index e292de6..e4a0c52 100644 --- a/app/history/[id]/page.tsx +++ b/app/history/[id]/page.tsx @@ -1,7 +1,7 @@ "use client"; import { use, useState, useRef } from "react"; -import { ArrowLeft, Send, Loader2, Eye } from "lucide-react"; +import { ArrowLeft, Send, Loader2, Eye, RefreshCw } from "lucide-react"; import Link from "next/link"; import { useSession, useMessages } from "@/lib/hooks"; import { timeAgo, formatTokens, platformBadgeClass } from "@/lib/utils"; @@ -96,6 +96,14 @@ export default function SessionReplayPage({ params }: { params: Promise<{ id: st )} + {/* Refresh */} + {/* Verbosity toggle */}