2b60dd2932
Persist platform_source across session creation, transcript ingestion, API query paths, and viewer state so Claude and Codex data can coexist without bleeding into each other. - add platform-source normalization helpers and persist platform_source in sdk_sessions via migration 24 with backfill and indexing - thread platformSource through CLI hooks, transcript processing, context generation, pagination, search routes, SSE payloads, and session management - expose source-aware project catalogs, viewer tabs, context preview selectors, and source badges for observations, prompts, and summaries - start the transcript watcher from the worker for transcript-based clients and preserve platform source during Codex ingestion - auto-start the worker from the MCP server for MCP-only clients and tighten stdio-driven cleanup during shutdown - keep createSDKSession backward compatible with existing custom-title callers while allowing explicit platform source forwarding
66 lines
2.4 KiB
TypeScript
66 lines
2.4 KiB
TypeScript
import React from "react";
|
|
import { Summary } from "../types";
|
|
import { formatDate } from "../utils/formatters";
|
|
|
|
interface SummaryCardProps {
|
|
summary: Summary;
|
|
}
|
|
|
|
export function SummaryCard({ summary }: SummaryCardProps) {
|
|
const date = formatDate(summary.created_at_epoch);
|
|
|
|
const sections = [
|
|
{ key: "investigated", label: "Investigated", content: summary.investigated, icon: "/icon-thick-investigated.svg" },
|
|
{ key: "learned", label: "Learned", content: summary.learned, icon: "/icon-thick-learned.svg" },
|
|
{ key: "completed", label: "Completed", content: summary.completed, icon: "/icon-thick-completed.svg" },
|
|
{ key: "next_steps", label: "Next Steps", content: summary.next_steps, icon: "/icon-thick-next-steps.svg" },
|
|
].filter((section) => section.content);
|
|
|
|
return (
|
|
<article className="card summary-card">
|
|
<header className="summary-card-header">
|
|
<div className="summary-badge-row">
|
|
<span className="card-type summary-badge">Session Summary</span>
|
|
<span className={`card-source source-${summary.platform_source || 'claude'}`}>
|
|
{summary.platform_source || 'claude'}
|
|
</span>
|
|
<span className="summary-project-badge">{summary.project}</span>
|
|
</div>
|
|
{summary.request && (
|
|
<h2 className="summary-title">{summary.request}</h2>
|
|
)}
|
|
</header>
|
|
|
|
<div className="summary-sections">
|
|
{sections.map((section, index) => (
|
|
<section
|
|
key={section.key}
|
|
className="summary-section"
|
|
style={{ animationDelay: `${index * 50}ms` }}
|
|
>
|
|
<div className="summary-section-header">
|
|
<img
|
|
src={section.icon}
|
|
alt={section.label}
|
|
className={`summary-section-icon summary-section-icon--${section.key}`}
|
|
/>
|
|
<h3 className="summary-section-label">{section.label}</h3>
|
|
</div>
|
|
<div className="summary-section-content">
|
|
{section.content}
|
|
</div>
|
|
</section>
|
|
))}
|
|
</div>
|
|
|
|
<footer className="summary-card-footer">
|
|
<span className="summary-meta-id">Session #{summary.id}</span>
|
|
<span className="summary-meta-divider">•</span>
|
|
<time className="summary-meta-date" dateTime={new Date(summary.created_at_epoch).toISOString()}>
|
|
{date}
|
|
</time>
|
|
</footer>
|
|
</article>
|
|
);
|
|
}
|