60 lines · 1.8 KB · TypeScript
RawDownload
import React from 'react'; import { format } from 'date-fns';import { Terminal } from 'lucide-react'; import type { SystemGroup } from '@renderer/types/groups'; // Module-level constant - safe because .replace() resets lastIndex on g-flagged regexesconst ANSI_ESCAPE_REGEX = new RegExp(String.fromCharCode(27) + '\\[[0-9;]*m', 'g'); interface SystemChatGroupProps {  systemGroup: SystemGroup;} /** * SystemChatGroup displays command output (e.g., /model response). * Renders on LEFT side like AI, but with neutral/gray styling. */const SystemChatGroupInner = ({  systemGroup,}: Readonly<SystemChatGroupProps>): React.JSX.Element => {  const { commandOutput, timestamp } = systemGroup;   // Clean ANSI escape codes from output  const cleanOutput = commandOutput.replace(ANSI_ESCAPE_REGEX, '');   return (    <div className="flex justify-start">      <div className="max-w-[85%] space-y-2">        {/* Header - system icon */}        <div          className="flex items-center gap-2 text-xs"          style={{ color: 'var(--color-text-muted)' }}        >          <Terminal className="size-3.5" style={{ color: 'var(--color-text-muted)' }} />          <span className="font-medium" style={{ color: 'var(--color-text-secondary)' }}>            System          </span>          <span>·</span>          <span>{format(timestamp, 'h:mm:ss a')}</span>        </div>         {/* Content - theme-aware neutral styling */}        <div          className="rounded-2xl rounded-bl-sm px-4 py-3"          style={{ backgroundColor: 'var(--chat-system-bg)' }}        >          <pre            className="whitespace-pre-wrap font-mono text-sm"            style={{ color: 'var(--chat-system-text)' }}          >            {cleanOutput}          </pre>        </div>      </div>    </div>  );}; export const SystemChatGroup = React.memo(SystemChatGroupInner);