messaging — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited messaging (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Components that render the active session: panel layout, header, messages list, individual message, plus the per-message slots (question, response, files, sources, action footer). All read state from ChatContext, so they only function inside <Chat>.
import {
SessionMessagePanel,
SessionMessagesHeader,
SessionMessages,
SessionMessage,
SessionEmpty,
MessageQuestion,
MessageResponse,
MessageFiles,
MessageSources,
MessageActions
} from 'reachat';Outer wrapper for the message column. Animates in/out, handles compact-mode "back to sessions" button, and slots in its children.
| Prop | Type | Default | Description |
|---|---|---|---|
allowBack | boolean | true | Render the back button in compact view (hidden when viewType === 'chat') |
children | ReactNode | — | Header / messages / input slots |
<SessionMessagePanel>
<SessionMessagesHeader />
<SessionMessages />
<ChatInput />
</SessionMessagePanel>The panel only renders when there is something to show: in companion mode, only when an activeSessionId is set; in console / chat mode, always.
Header for the active session — renders the title (with Ellipsis) and creation date (DateFormat). Hidden when no session is active. Accepts children to override the default content (Radix Slot):
<SessionMessagesHeader>
<div className="flex items-center justify-between gap-2">
<h2>{activeSession?.title}</h2>
<Button>Share</Button>
</div>
</SessionMessagesHeader>Renders the conversations of the activeSession. Handles client-side pagination via reablocks useInfinityList, optional auto-scroll to bottom, and a "scroll to bottom" floating button.
| Prop | Type | Default | Description | |
|---|---|---|---|---|
limit | `number \ | null` | 10 | Client-side page size; null disables paging and renders the full list |
showMoreText | string | 'Show more' | Label for the load-more button | |
autoScroll | boolean | true | Scroll to bottom when the active session changes or animation finishes | |
showScrollBottomButton | boolean | — | Show floating "scroll to bottom" button when not at bottom | |
showLoadMoreButton | boolean | false | Force-show the "show more" button (otherwise shown only when hasMore) | |
loadMoreButtonDisabled | boolean | — | Disable the load-more button | |
newSessionContent | `string \ | ReactNode` | — | Forwarded to SessionEmpty when no session is active |
onScroll | UIEventHandler<HTMLDivElement> | — | Captures scroll on the scroll container | |
onLoadMore | () => void | — | Replace built-in pagination — fires when load-more is clicked | |
children | (conversations: Conversation[]) => ReactNode | — | Render-prop override; if omitted, renders <SessionMessage /> per conversation |
<SessionMessages
limit={20}
autoScroll
showScrollBottomButton
onLoadMore={fetchOlderConversations}
>
{convos => convos.map(c => <SessionMessage key={c.id} conversation={c} />)}
</SessionMessages>When no session is active, SessionMessages falls back to <SessionEmpty>{newSessionContent}</SessionEmpty> (renders theme.empty).
Renders a single conversation as a card with the four sub-components (question, response, sources, actions). Uses Framer Motion for staggered entry animation (configured by the parent SessionMessages container).
| Prop | Type | Default | Description |
|---|---|---|---|
conversation | Conversation | — | Conversation data |
isLast | boolean | — | Marks the streaming message — controls the loading cursor on MessageResponse |
className | string | — | Class for the inner Card |
children | ReactNode | — | Override the default sub-component layout |
<SessionMessage conversation={conv} isLast={isStreaming}>
<MessageQuestion question={conv.question} files={conv.files} />
<MessageResponse response={conv.response} isLoading={isStreaming} />
<MessageSources sources={conv.sources} />
<MessageActions question={conv.question} response={conv.response} onUpvote={...} />
</SessionMessage>The default body checks isLast && isLoading from context to show the typing cursor on MessageResponse.
Question block: renders Markdown with the chat's remarkPlugins, plus attached files and a "Show more" button when the question is long (>500 chars).
| Prop | Type | Default | Description |
|---|---|---|---|
question | string | — | Markdown question string |
files | ConversationFile[] | — | File attachments rendered above the text |
children | ReactNode | — | Override (Radix Slot) |
Response markdown with an animated streaming cursor when isLoading is true. Renders inside a data-compact wrapper for compact-mode targeting.
| Prop | Type | Default | Description |
|---|---|---|---|
response | string | — | Markdown response string |
isLoading | boolean | — | Show the blinking cursor |
Renders Conversation.files. Image files (type starts with image/) and other files are grouped separately. When more than 3 image files, the rest collapse behind a +N overlay that expands on click.
| Prop | Type | Default | Description |
|---|---|---|---|
files | ConversationFile[] | — | Files to render |
children | ReactNode | — | Override (default MessageFile) |
Renders Conversation.sources as cards using the default MessageSource component. Hidden when sources is empty.
| Prop | Type | Default | Description |
|---|---|---|---|
sources | ConversationSource[] | — | Sources to render |
children | ReactNode | — | Override slot for custom source rendering |
Footer with copy / upvote / downvote / refresh icon buttons. Renders only when at least one icon prop is provided. Defaults copy the question + response to the clipboard.
| Prop | Type | Default | Description | |
|---|---|---|---|---|
question | string | — | Used by the default copy handler | |
response | string | — | Used by the default copy handler | |
copyIcon / thumbsUpIcon / thumbsDownIcon / refreshIcon | `ReactElement \ | null` | reachat icons | Pass null to hide a button |
onCopy / onUpvote / onDownvote / onRefresh | () => void | — | Handlers (default onCopy writes question\nresponse to the clipboard) | |
children | ReactNode | — | Override the entire footer |
Empty-state shown by SessionMessages when no session is active. Renders newSessionContent inside theme.empty.
<SessionEmpty>Start a new conversation</SessionEmpty>theme.messages.{base, console, companion, back, inner, title, date, content, header, showMore}
theme.messages.message.{base, question, response, cursor, overlay, expand, scrollToBottom: { container, button }}
theme.messages.message.files.{base, file: { base, name }}
theme.messages.message.sources.{base, source: { base, companion, image, title, url }}
theme.messages.message.markdown.{hr, p, a, table, th, td, code, inlineCode, toolbar, li, ul, ol, copy, h1..h6}
theme.messages.message.footer.{base, copy, upvote, downvote, refresh}~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.