crucıble

Colloquy

Agent chat panel composing the AI set — a role="log" transcript of right-aligned user bubbles and unbubbled assistant turns (thinking disclosure, inline tool-call cards on a progress spine, an inline approval request, a streamed answer) above a pinned prompt composer. Auto-scroll follows the stream only while you're at the bottom; scrolling up detaches it behind a spring-in "Jump to latest" pill. Empty-state greeting with suggestion chips, rise-in messages, and a seeded useScriptedConversation hook that waits on approvals. Instant scroll and fades under reduced motion.

motionpro

Installation

CLI

npx shadcn@latest add @crucible/colloquy

Manual — install dependencies, then copy the source

npm install motion

Props

PropTypeDefaultDescription
messagesColloquyMessage[][]The controlled transcript, oldest first. An empty list shows the greeting and suggestions.
onSend(text: string) => voidFires with the trimmed text when the user sends a message (Enter, the send button, or a suggestion in "send" mode).
busybooleanfalseThe assistant is working: the composer shows a stop button and blocks Enter.
onStop() => voidFires from the composer's stop button or Escape while busy.
suggestionsstring[]Suggestion chips shown in the empty state. Pass [] to hide them.
suggestionAction"fill" | "send""fill"What clicking a suggestion does: "fill" puts it in the composer, "send" sends it right away.
greetingReact.ReactNode"How can I help?"Heading of the empty state.
placeholderstring"Ask anything…"Composer placeholder.
draftstringControlled composer draft. Pair with onDraftChange.
defaultDraftstring""Initial composer draft when uncontrolled.
onDraftChange(draft: string) => voidFires with the next draft on every edit and when a suggestion fills the composer.
composerPropsOmit< SluiceProps, "value" | "defaultValue" | "onValueChange" | "onSubmit" | "busy" | "onStop" | "placeholder" | "accentColor" >Extra props for the underlying Sluice composer (e.g. models, hideAttach={false}).
followThresholdnumber48How far from the bottom (px) still counts as "following the stream".
accentColorstring"#a78bfa" (ion violet)Accent for the composer, streaming caret, tool spine, approval button and focus rings.
Also accepts all props of Omit<React.ComponentPropsWithoutRef<"section">, "children" | "onSubmit"> — they pass through to the underlying element.

Honors prefers-reduced-motion with a designed static fallback, and passes className through.