import { memo } from "react"; import ReactMarkdown from "react-markdown"; import remarkGfm from "remark-gfm"; import type { Components } from "react-markdown"; import type { PluggableList } from "unified"; import { linkifyReactChildren } from "../utils/filePathLinkify"; import { sharedRehypePlugins, createMermaidCodeComponent } from "./markdownPipeline"; /* FNXC:Markdown 2026-06-23-03:30: The sanitize schema, rehype plugin chain (rehype-raw -> rehype-sanitize), and the mermaid-aware code component now live in ./markdownPipeline so the task description + summary in TaskDetailModal share the exact same XSS posture. This component consumes those shared exports; see markdownPipeline.tsx for the rationale. */ const mailboxMarkdownComponents: Components = { p: ({ children, ...props }) =>

{linkifyReactChildren(children)}

, li: ({ children, ...props }) =>
  • {linkifyReactChildren(children)}
  • , pre: ({ children, ...props }) => (
          {children}
        
    ), table: ({ children, ...props }) => ( {children}
    ), // Code-block override: fenced ```mermaid renders as a diagram; all other code // keeps default rendering. See createMermaidCodeComponent in markdownPipeline. code: createMermaidCodeComponent("mailbox-mermaid-diagram"), // Open links in a new tab. Sanitize strips javascript: URLs and event handlers // before this runs, so href is safe. a: ({ children, ...props }) => ( {children} ), }; const remarkPlugins: PluggableList = [remarkGfm]; interface MailboxMessageContentProps { /** Raw message body. Rendered as GitHub-flavored markdown. */ content: string; /** Optional extra class for the wrapper. */ className?: string; /** Optional data-testid for test selectors. */ testId?: string; } /** * Renders a mailbox message body as GitHub-flavored markdown. * * Supports embedded raw HTML (details/summary/kbd/sub/tables) via rehype-raw, with * rehype-sanitize stripping XSS (script/style/iframe/event-handlers/javascript:). * Fenced ```mermaid blocks render as diagrams via the lazy-loaded MermaidDiagram. * HTML comments (``) are dropped and never rendered. * * Memoized because mailbox detail panes can re-render on selection / SSE * updates while the underlying message body is unchanged. */ export const MailboxMessageContent = memo(function MailboxMessageContent({ content, className, testId, }: MailboxMessageContentProps) { const wrapperClass = className ? `mailbox-markdown ${className}` : "mailbox-markdown"; return (
    {content}
    ); });