@assistant-ui/mcp-docs-server 0.1.27 → 0.1.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/.docs/organized/code-examples/waterfall.md +1 -1
  2. package/.docs/organized/code-examples/with-a2a.md +1 -1
  3. package/.docs/organized/code-examples/with-ag-ui.md +2 -2
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +3 -3
  5. package/.docs/organized/code-examples/with-artifacts.md +3 -3
  6. package/.docs/organized/code-examples/with-assistant-transport.md +1 -1
  7. package/.docs/organized/code-examples/with-chain-of-thought.md +3 -3
  8. package/.docs/organized/code-examples/with-cloud-standalone.md +3 -3
  9. package/.docs/organized/code-examples/with-cloud.md +3 -3
  10. package/.docs/organized/code-examples/with-custom-thread-list.md +3 -3
  11. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +5 -5
  12. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +5 -5
  13. package/.docs/organized/code-examples/with-expo.md +3 -3
  14. package/.docs/organized/code-examples/with-external-store.md +1 -1
  15. package/.docs/organized/code-examples/with-ffmpeg.md +3 -3
  16. package/.docs/organized/code-examples/with-generative-ui.md +841 -0
  17. package/.docs/organized/code-examples/with-google-adk.md +1 -1
  18. package/.docs/organized/code-examples/with-heat-graph.md +1 -1
  19. package/.docs/organized/code-examples/with-interactables.md +3 -3
  20. package/.docs/organized/code-examples/with-langgraph.md +2 -2
  21. package/.docs/organized/code-examples/with-livekit.md +4 -4
  22. package/.docs/organized/code-examples/with-parent-id-grouping.md +2 -2
  23. package/.docs/organized/code-examples/with-react-hook-form.md +4 -4
  24. package/.docs/organized/code-examples/with-react-router.md +2 -2
  25. package/.docs/organized/code-examples/with-store.md +1 -1
  26. package/.docs/organized/code-examples/with-tanstack.md +2 -2
  27. package/.docs/organized/code-examples/with-tap-runtime.md +1 -1
  28. package/.docs/raw/docs/(docs)/guides/mentions.mdx +406 -0
  29. package/.docs/raw/docs/(docs)/guides/slash-commands.mdx +275 -0
  30. package/.docs/raw/docs/primitives/composer.mdx +27 -4
  31. package/package.json +3 -3
@@ -0,0 +1,275 @@
1
+ ---
2
+ title: Slash Commands
3
+ description: Let users type / in the composer to trigger predefined actions from a popover picker.
4
+ ---
5
+
6
+ Slash commands let users type `/` in the composer to open a popover, browse available commands, and execute one. Unlike [mentions](/docs/guides/mentions) (which insert text into the message), slash commands trigger **actions** — the `/command` text is removed from the composer and a callback fires.
7
+
8
+ ## How It Works
9
+
10
+ ```
11
+ User types "/" → Trigger detected → Adapter provides commands
12
+
13
+ Command executed ← User selects command from popover
14
+
15
+ "/command" text removed from composer
16
+ ```
17
+
18
+ The slash command system is built on the same [trigger popover architecture](#trigger-popover-architecture) as mentions. It has two layers:
19
+
20
+ 1. **Adapter** — provides the list of available commands (flat list by default, or categorized for advanced use)
21
+ 2. **SlashCommandRoot** — a convenience wrapper that pre-configures the trigger character (`/`) and action-based select behavior
22
+
23
+ ## Quick Start
24
+
25
+ ### 1. Define Commands
26
+
27
+ ```tsx
28
+ import {
29
+ unstable_useSlashCommandAdapter,
30
+ ComposerPrimitive,
31
+ } from "@assistant-ui/react";
32
+
33
+ // Define commands outside the component for a stable reference
34
+ const COMMANDS = [
35
+ {
36
+ name: "summarize",
37
+ description: "Summarize the conversation",
38
+ execute: () => console.log("Summarize!"),
39
+ },
40
+ {
41
+ name: "translate",
42
+ description: "Translate text to another language",
43
+ execute: () => console.log("Translate!"),
44
+ },
45
+ {
46
+ name: "help",
47
+ description: "List all available commands",
48
+ },
49
+ ];
50
+
51
+ function MyComposer() {
52
+ const slashAdapter = unstable_useSlashCommandAdapter({
53
+ commands: COMMANDS,
54
+ });
55
+
56
+ return (
57
+ <ComposerPrimitive.Unstable_SlashCommandRoot adapter={slashAdapter}>
58
+ <ComposerPrimitive.Root>
59
+ <ComposerPrimitive.Input placeholder="Type / for commands..." />
60
+ <ComposerPrimitive.Send>Send</ComposerPrimitive.Send>
61
+
62
+ <ComposerPrimitive.Unstable_TriggerPopoverPopover className="popover">
63
+ <ComposerPrimitive.Unstable_TriggerPopoverItems>
64
+ {(items) =>
65
+ items.map((item, index) => (
66
+ <ComposerPrimitive.Unstable_TriggerPopoverItem
67
+ key={item.id}
68
+ item={item}
69
+ index={index}
70
+ className="popover-item"
71
+ >
72
+ <strong>{item.label}</strong>
73
+ {item.description && <span>{item.description}</span>}
74
+ </ComposerPrimitive.Unstable_TriggerPopoverItem>
75
+ ))
76
+ }
77
+ </ComposerPrimitive.Unstable_TriggerPopoverItems>
78
+ </ComposerPrimitive.Unstable_TriggerPopoverPopover>
79
+ </ComposerPrimitive.Root>
80
+ </ComposerPrimitive.Unstable_SlashCommandRoot>
81
+ );
82
+ }
83
+ ```
84
+
85
+ ### 2. Handle Command Selection
86
+
87
+ There are two ways to handle command execution:
88
+
89
+ **Via `execute` on each item** — define the action inline in the command definition:
90
+
91
+ ```ts
92
+ { name: "summarize", execute: () => runSummarize() }
93
+ ```
94
+
95
+ **Via `onSelect` prop** — handle all commands in one place:
96
+
97
+ ```tsx
98
+ <ComposerPrimitive.Unstable_SlashCommandRoot
99
+ adapter={slashAdapter}
100
+ onSelect={(item) => {
101
+ switch (item.id) {
102
+ case "summarize": runSummarize(); break;
103
+ case "translate": runTranslate(); break;
104
+ }
105
+ }}
106
+ >
107
+ ```
108
+
109
+ Both `execute` and `onSelect` fire when a command is selected. Use whichever pattern fits your code.
110
+
111
+ ## Custom Adapter
112
+
113
+ The `unstable_useSlashCommandAdapter` hook uses a **flat list** — all commands show immediately when `/` is typed, with search filtering as the user types. This is the recommended UX for most cases.
114
+
115
+ For **categorized navigation** (drill-down into groups), build the adapter manually. Return categories from `categories()` and items from `categoryItems()`. The popover will show categories first, then items within the selected category:
116
+
117
+ ```ts
118
+ import type { Unstable_SlashCommandAdapter } from "@assistant-ui/core";
119
+
120
+ const adapter: Unstable_SlashCommandAdapter = {
121
+ categories() {
122
+ return [
123
+ { id: "actions", label: "Actions" },
124
+ { id: "export", label: "Export" },
125
+ ];
126
+ },
127
+
128
+ categoryItems(categoryId) {
129
+ if (categoryId === "actions") {
130
+ return [
131
+ { id: "summarize", type: "command", label: "/summarize", description: "Summarize the conversation" },
132
+ { id: "translate", type: "command", label: "/translate", description: "Translate text" },
133
+ ];
134
+ }
135
+ if (categoryId === "export") {
136
+ return [
137
+ { id: "pdf", type: "command", label: "/export pdf", description: "Export as PDF" },
138
+ { id: "markdown", type: "command", label: "/export md", description: "Export as Markdown" },
139
+ ];
140
+ }
141
+ return [];
142
+ },
143
+
144
+ // Optional — enables search across all categories
145
+ search(query) {
146
+ const lower = query.toLowerCase();
147
+ const all = [...this.categoryItems("actions"), ...this.categoryItems("export")];
148
+ return all.filter(
149
+ (item) => item.label.toLowerCase().includes(lower) || item.description?.toLowerCase().includes(lower),
150
+ );
151
+ },
152
+ };
153
+ ```
154
+
155
+ When using a categorized adapter, add `TriggerPopoverCategories` to your popover UI:
156
+
157
+ ```tsx
158
+ <ComposerPrimitive.Unstable_TriggerPopoverPopover>
159
+ <ComposerPrimitive.Unstable_TriggerPopoverBack>← Back</ComposerPrimitive.Unstable_TriggerPopoverBack>
160
+ <ComposerPrimitive.Unstable_TriggerPopoverCategories>
161
+ {(categories) => categories.map((cat) => (
162
+ <ComposerPrimitive.Unstable_TriggerPopoverCategoryItem key={cat.id} categoryId={cat.id}>
163
+ {cat.label}
164
+ </ComposerPrimitive.Unstable_TriggerPopoverCategoryItem>
165
+ ))}
166
+ </ComposerPrimitive.Unstable_TriggerPopoverCategories>
167
+ <ComposerPrimitive.Unstable_TriggerPopoverItems>
168
+ {(items) => items.map((item, index) => (
169
+ <ComposerPrimitive.Unstable_TriggerPopoverItem key={item.id} item={item} index={index}>
170
+ {item.label}
171
+ </ComposerPrimitive.Unstable_TriggerPopoverItem>
172
+ ))}
173
+ </ComposerPrimitive.Unstable_TriggerPopoverItems>
174
+ </ComposerPrimitive.Unstable_TriggerPopoverPopover>
175
+ ```
176
+
177
+ ## Combining with Mentions
178
+
179
+ Slash commands and mentions can coexist on the same composer. Nest both roots — the [plugin protocol](#trigger-popover-architecture) ensures they don't conflict:
180
+
181
+ ```tsx
182
+ <ComposerPrimitive.Unstable_MentionRoot adapter={mentionAdapter}>
183
+ <ComposerPrimitive.Unstable_SlashCommandRoot adapter={slashAdapter}>
184
+ <ComposerPrimitive.Root>
185
+ <ComposerPrimitive.Input placeholder="Type @ to mention, / for commands..." />
186
+ <ComposerPrimitive.Send>Send</ComposerPrimitive.Send>
187
+
188
+ {/* Mention popover — shows when @ is typed */}
189
+ <ComposerPrimitive.Unstable_MentionPopover>
190
+ <ComposerPrimitive.Unstable_MentionCategories>
191
+ {(categories) => categories.map((cat) => (
192
+ <ComposerPrimitive.Unstable_MentionCategoryItem key={cat.id} categoryId={cat.id}>
193
+ {cat.label}
194
+ </ComposerPrimitive.Unstable_MentionCategoryItem>
195
+ ))}
196
+ </ComposerPrimitive.Unstable_MentionCategories>
197
+ <ComposerPrimitive.Unstable_MentionItems>
198
+ {(items) => items.map((item) => (
199
+ <ComposerPrimitive.Unstable_MentionItem key={item.id} item={item}>
200
+ {item.label}
201
+ </ComposerPrimitive.Unstable_MentionItem>
202
+ ))}
203
+ </ComposerPrimitive.Unstable_MentionItems>
204
+ </ComposerPrimitive.Unstable_MentionPopover>
205
+
206
+ {/* Slash command popover — shows when / is typed */}
207
+ <ComposerPrimitive.Unstable_TriggerPopoverPopover>
208
+ <ComposerPrimitive.Unstable_TriggerPopoverItems>
209
+ {(items) => items.map((item, index) => (
210
+ <ComposerPrimitive.Unstable_TriggerPopoverItem key={item.id} item={item} index={index}>
211
+ {item.label}
212
+ </ComposerPrimitive.Unstable_TriggerPopoverItem>
213
+ ))}
214
+ </ComposerPrimitive.Unstable_TriggerPopoverItems>
215
+ </ComposerPrimitive.Unstable_TriggerPopoverPopover>
216
+ </ComposerPrimitive.Root>
217
+ </ComposerPrimitive.Unstable_SlashCommandRoot>
218
+ </ComposerPrimitive.Unstable_MentionRoot>
219
+ ```
220
+
221
+ Each root provides its own `TriggerPopoverContext`. When the user types `@`, the mention popover opens. When they type `/`, the slash command popover opens. Keyboard events route to whichever popover is active.
222
+
223
+ ## Keyboard Navigation
224
+
225
+ Same keyboard bindings as mentions:
226
+
227
+ | Key | Action |
228
+ | --- | --- |
229
+ | <Kbd>ArrowDown</Kbd> | Highlight next item |
230
+ | <Kbd>ArrowUp</Kbd> | Highlight previous item |
231
+ | <Kbd>Enter</Kbd> | Execute highlighted command / drill into category |
232
+ | <Kbd>Escape</Kbd> | Close popover |
233
+ | <Kbd>Backspace</Kbd> | Go back to categories (when query is empty) |
234
+
235
+ ## Trigger Popover Architecture
236
+
237
+ Both mentions and slash commands are built on a generic **trigger popover** system:
238
+
239
+ - `ComposerPrimitive.Unstable_TriggerPopoverRoot` — the generic root, parameterized by trigger character and select behavior
240
+ - `ComposerPrimitive.Unstable_MentionRoot` — preset with `trigger="@"` and `onSelect: insertDirective`
241
+ - `ComposerPrimitive.Unstable_SlashCommandRoot` — preset with `trigger="/"` and `onSelect: action`
242
+
243
+ The trigger popover primitives (`TriggerPopoverPopover`, `TriggerPopoverItems`, etc.) are shared across both. You can also use `TriggerPopoverRoot` directly to build custom trigger systems with other characters (e.g. `:` for emoji).
244
+
245
+ ### ComposerInput Plugin Protocol
246
+
247
+ Under the hood, each trigger root registers a **ComposerInputPlugin** with the composer input. This is a generic protocol that decouples the input from any specific trigger:
248
+
249
+ ```ts
250
+ type ComposerInputPlugin = {
251
+ handleKeyDown(e: KeyboardEvent): boolean;
252
+ setCursorPosition(pos: number): void;
253
+ };
254
+ ```
255
+
256
+ The input iterates over registered plugins for keyboard events and cursor changes. This is what enables multiple trigger roots to coexist without conflict.
257
+
258
+ ## Primitives Reference
259
+
260
+ | Primitive | Description |
261
+ | --- | --- |
262
+ | `Unstable_SlashCommandRoot` | Convenience wrapper — `TriggerPopoverRoot` with `trigger="/"` and action behavior |
263
+ | `Unstable_TriggerPopoverRoot` | Generic root — configurable trigger character and select behavior |
264
+ | `Unstable_TriggerPopoverPopover` | Container — only renders when a trigger is active (`role="listbox"`) |
265
+ | `Unstable_TriggerPopoverCategories` | Render-function for the top-level category list |
266
+ | `Unstable_TriggerPopoverCategoryItem` | Button that drills into a category (`role="option"`, auto `data-highlighted`) |
267
+ | `Unstable_TriggerPopoverItems` | Render-function for items within the active category or search results |
268
+ | `Unstable_TriggerPopoverItem` | Button that selects an item (`role="option"`, auto `data-highlighted`) |
269
+ | `Unstable_TriggerPopoverBack` | Button that navigates back from items to categories |
270
+
271
+ ## Related
272
+
273
+ - [Mentions Guide](/docs/guides/mentions) — `@`-mention system built on the same architecture
274
+ - [Suggestions Guide](/docs/guides/suggestions) — static follow-up prompts (different from slash commands)
275
+ - [Composer Primitives](/docs/primitives/composer) — underlying composer primitives
@@ -102,19 +102,42 @@ import { ComposerPrimitive } from "@assistant-ui/react";
102
102
 
103
103
  The primitive's behavior (keyboard handling, disabled state, form submission) is merged onto your element. Your styles, your component, primitive wiring.
104
104
 
105
- ### Unstable Mentions
105
+ ### Unstable Trigger Popovers
106
106
 
107
- Composer also includes an unstable mention system for `@`-triggered popovers. It is built around `ComposerPrimitive.Unstable_MentionRoot` and intended for rich inputs like `LexicalComposerInput`.
107
+ Composer includes an unstable **trigger popover** system for character-triggered popovers (e.g. `@` for mentions, `/` for slash commands). Multiple triggers can coexist on the same input.
108
+
109
+ **Mentions** (`@` trigger) — insert directive text into the message:
108
110
 
109
111
  ```tsx
110
- <ComposerPrimitive.Unstable_MentionRoot>
112
+ <ComposerPrimitive.Unstable_MentionRoot adapter={mentionAdapter}>
111
113
  <ComposerPrimitive.Root>
112
- <LexicalComposerInput placeholder="Type @ to mention a tool..." />
114
+ <ComposerPrimitive.Input placeholder="Type @ to mention..." />
113
115
  <ComposerPrimitive.Unstable_MentionPopover />
114
116
  </ComposerPrimitive.Root>
115
117
  </ComposerPrimitive.Unstable_MentionRoot>
116
118
  ```
117
119
 
120
+ **Slash commands** (`/` trigger) — execute an action and clear the command text:
121
+
122
+ ```tsx
123
+ <ComposerPrimitive.Unstable_SlashCommandRoot adapter={slashAdapter}>
124
+ <ComposerPrimitive.Root>
125
+ <ComposerPrimitive.Input placeholder="Type / for commands..." />
126
+ <ComposerPrimitive.Unstable_TriggerPopoverPopover>
127
+ <ComposerPrimitive.Unstable_TriggerPopoverItems>
128
+ {(items) => items.map(item => (
129
+ <ComposerPrimitive.Unstable_TriggerPopoverItem key={item.id} item={item}>
130
+ {item.label}
131
+ </ComposerPrimitive.Unstable_TriggerPopoverItem>
132
+ ))}
133
+ </ComposerPrimitive.Unstable_TriggerPopoverItems>
134
+ </ComposerPrimitive.Unstable_TriggerPopoverPopover>
135
+ </ComposerPrimitive.Root>
136
+ </ComposerPrimitive.Unstable_SlashCommandRoot>
137
+ ```
138
+
139
+ See the [Mentions guide](/docs/guides/mentions) and [Slash Commands guide](/docs/guides/slash-commands) for full documentation.
140
+
118
141
  ## Parts
119
142
 
120
143
  ### Root
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/mcp-docs-server",
3
- "version": "0.1.27",
3
+ "version": "0.1.28",
4
4
  "description": "MCP server for assistant-ui documentation and examples",
5
5
  "keywords": [
6
6
  "mcp",
@@ -37,10 +37,10 @@
37
37
  "zod": "^4.3.6"
38
38
  },
39
39
  "devDependencies": {
40
- "@types/node": "^25.5.0",
40
+ "@types/node": "^25.5.2",
41
41
  "tsx": "^4.21.0",
42
42
  "vitest": "^4.1.2",
43
- "@assistant-ui/x-buildutils": "0.0.3"
43
+ "@assistant-ui/x-buildutils": "0.0.4"
44
44
  },
45
45
  "publishConfig": {
46
46
  "access": "public",