Rich composer
The desktop app's Tiptap composer as a React component, with completions, typed badges, ghost text, prompt modes, history, attachments and a draft shared across windows, over a composer host.
zidane-ui/chat/rich-composer holds the desktop app's composer: RichComposer. It completes @ files, / commands and skills, # chats and extension triggers, shows links and commands as badges while you type, offers ghost text and the next prompt, has a shell mode (!) and a transcript search mode (?), recalls earlier prompts with ↑ / ↓, stages attachments, and shares its draft with every window on the same session. It reads a ComposerHost. Sending stays yours: onSend gets the text, the attachments and the skills it activates.
It is its own entry point, so an app that uses only Composer never loads it. The previews below run on the fixture host. Type / or @ to open a popover, or git sta to see ghost text.
Mount it#
Wrap the composer in a ComposerHostProvider and a PromptHistoryProvider (both from zidane-ui/chat/composer). Pass the session, the folder, and what sending does.
import 'zidane-ui/styles.css'
import { ComposerHostProvider, PromptHistoryProvider } from 'zidane-ui/chat/composer'
import { RichComposer } from 'zidane-ui/chat/rich-composer'
export function Prompt({ host, sessionId, folder, send }) {
return (
<ComposerHostProvider host={host}>
<PromptHistoryProvider>
<RichComposer
disabled={false}
folderPath={folder}
activeSessionId={sessionId}
hostId={null}
onSend={(text, attachments, skills) => send({ text, attachments, skills })}
inlineAutocomplete
/>
</PromptHistoryProvider>
</ComposerHostProvider>
)
}AppHostProvider (zidane-ui/app) puts host.composer in a ComposerHostProvider for you. Reject from onSend to put the prompt back in an empty composer.
Slots and options:
leadingActionsandtrailingActionssit beside the + button and before Send (the desktop app puts its pickers and status pills there).badgesis the band above the card.footersits in the tray under it.attachmentsEnabled,inlineAutocompleteandpromptSuggestionsturn the attachment folding, the ghost text and the next-prompt ghost on or off.scopeKeynames the composer on the composer bus (pushComposerPrompt,pushComposerAttachment,pushComposerMentionfromzidane-ui/chat/composer), so a panel can push content into it.commandArgsshares the commands' argument values with the rest of your app,siteIconsdraws favicons in link badges, andattachmentLabelandtextPreviewset how attachment tiles and text previews look.- The search mode reports its query with
onSearchQueryChangeand takes the match counter back assearchStatus.
Pick a host#
| Host | From | Talks to |
|---|---|---|
createServerComposerHost({ client }) | zidane-ui/adapters | zidane-server. Pass the client of your chat host (createServerHost(…).client). |
createFixtureComposerHost(options) | zidane-ui/chat/testing | Memory, for demos and tests. |
| Your own | zidane-ui/chat/headless | Anything that implements ComposerHost. |
zidane-server runs the extensions' completions (completions.providers, completions.suggest, completions.submit), so the server host offers the extension members. @ lists a folder's files on the server (files.list, read again after a tool result), # its sessions (sessions.listMeta, read again on sessions:changed), and completions.locationOf is the folder's checkout and project there (files.location). It has no call to resolve ghost text for a new chat: the server host answers none before the chat has a session.
What a host offers#
Every member is optional. A member you leave out turns off what needs it.
| Member | What it does | Left out |
|---|---|---|
drafts | The draft per session, its staged files, and the edits other windows make | Each window keeps its own draft |
completions.files | The files @ lists | @ lists nothing |
completions.commands, commandArgs | The / commands and their argument values | / lists skills only |
completions.chats | The sessions # can reference | # lists nothing |
completions.watchSkills | The enabled skills, as they change | / lists commands only |
completions.watchExtensionProviders, extensionItems, submit | Extension completion triggers, their items, and their submit hooks | No extension popovers |
completions.locationOf | A folder's checkout and project roots | # cannot scope to the project |
autocomplete | Ghost text, and ghost text another window resolved | No ghost text |
suggestions | The next prompt once a run ends, and when it goes stale | No next-prompt ghost |
The contract every implementation runs is describeComposerHostContract in zidane-ui/chat/testing/contract.
Related#
- Composer: the kit's plain composer, its pickers and its badge strip.
- The desktop composer: what the composer does in Zidane Desktop.