@assistant-ui/mcp-docs-server 0.2.1 → 0.2.3

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 (187) hide show
  1. package/.docs/organized/code-examples/waterfall.md +3 -3
  2. package/.docs/organized/code-examples/with-a2a.md +5 -4
  3. package/.docs/organized/code-examples/with-ag-ui.md +7 -6
  4. package/.docs/organized/code-examples/with-ai-sdk-v7.md +14 -13
  5. package/.docs/organized/code-examples/with-artifacts.md +12 -11
  6. package/.docs/organized/code-examples/with-assistant-transport.md +6 -5
  7. package/.docs/organized/code-examples/with-browser-extension.md +6 -6
  8. package/.docs/organized/code-examples/with-chain-of-thought.md +16 -14
  9. package/.docs/organized/code-examples/with-cloud-standalone.md +7 -7
  10. package/.docs/organized/code-examples/with-cloud.md +11 -10
  11. package/.docs/organized/code-examples/with-custom-thread-list.md +11 -10
  12. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +14 -13
  13. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +15 -14
  14. package/.docs/organized/code-examples/with-eve.md +6 -5
  15. package/.docs/organized/code-examples/with-expo.md +213 -36
  16. package/.docs/organized/code-examples/with-external-store.md +6 -5
  17. package/.docs/organized/code-examples/with-ffmpeg.md +11 -10
  18. package/.docs/organized/code-examples/with-generative-ui.md +263 -29
  19. package/.docs/organized/code-examples/with-google-adk.md +5 -4
  20. package/.docs/organized/code-examples/with-heat-graph.md +3 -3
  21. package/.docs/organized/code-examples/with-image-generation.md +8 -7
  22. package/.docs/organized/code-examples/with-interactables.md +11 -10
  23. package/.docs/organized/code-examples/with-langchain.md +10 -9
  24. package/.docs/organized/code-examples/with-langgraph.md +7 -6
  25. package/.docs/organized/code-examples/with-livekit.md +15 -14
  26. package/.docs/organized/code-examples/with-mcp.md +14 -12
  27. package/.docs/organized/code-examples/with-nuxt.md +511 -575
  28. package/.docs/organized/code-examples/with-opencode.md +4 -4
  29. package/.docs/organized/code-examples/with-openui.md +450 -0
  30. package/.docs/organized/code-examples/with-pi.md +6 -5
  31. package/.docs/organized/code-examples/with-react-hook-form.md +16 -13
  32. package/.docs/organized/code-examples/with-react-ink-web.md +65 -15
  33. package/.docs/organized/code-examples/with-react-ink.md +5 -4
  34. package/.docs/organized/code-examples/with-react-router.md +8 -7
  35. package/.docs/organized/code-examples/with-resumable-stream.md +13 -12
  36. package/.docs/organized/code-examples/with-store.md +3 -3
  37. package/.docs/organized/code-examples/with-svelte.md +415 -0
  38. package/.docs/organized/code-examples/with-sveltekit.md +1061 -0
  39. package/.docs/organized/code-examples/with-tanstack.md +10 -9
  40. package/.docs/organized/code-examples/with-tap-runtime.md +5 -4
  41. package/.docs/organized/code-examples/with-virtualized-thread.md +6 -5
  42. package/.docs/organized/code-examples/with-vue.md +2 -2
  43. package/.docs/raw/docs/{(docs) → (getting-started)}/cli.mdx +6 -1
  44. package/.docs/raw/docs/{(docs) → (getting-started)}/devtools.mdx +1 -1
  45. package/.docs/raw/docs/{(docs) → (getting-started)}/index.mdx +4 -2
  46. package/.docs/raw/docs/{(docs) → (getting-started)}/installation.mdx +26 -26
  47. package/.docs/raw/docs/(reference)/api-reference/adapters/suggestions.mdx +6 -0
  48. package/.docs/raw/docs/(reference)/api-reference/context-providers/assistant-runtime-provider.mdx +1 -1
  49. package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +6 -1
  50. package/.docs/raw/docs/(reference)/api-reference/generative-ui/slack.mdx +5 -1
  51. package/.docs/raw/docs/(reference)/api-reference/generative-ui/teams.mdx +9 -2
  52. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +2 -2
  53. package/.docs/raw/docs/(reference)/api-reference/integrations/{react-ai-sdk.mdx → ai-sdk.mdx} +43 -18
  54. package/.docs/raw/docs/(reference)/api-reference/integrations/eve.mdx +61 -2
  55. package/.docs/raw/docs/(reference)/api-reference/integrations/index.mdx +3 -3
  56. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +2 -2
  57. package/.docs/raw/docs/(reference)/api-reference/primitives/composer.mdx +20 -2
  58. package/.docs/raw/docs/(reference)/api-reference/tools/interactables.mdx +1 -1
  59. package/.docs/raw/docs/(reference)/api-reference/tools/status.mdx +1 -1
  60. package/.docs/raw/docs/(reference)/api-reference/transport/frame.mdx +1 -1
  61. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +32 -1
  62. package/.docs/raw/docs/(reference)/api-reference/voice/session.mdx +1 -1
  63. package/.docs/raw/docs/cloud/ai-sdk-assistant-ui.mdx +10 -10
  64. package/.docs/raw/docs/cloud/ai-sdk.mdx +4 -2
  65. package/.docs/raw/docs/cloud/index.mdx +1 -1
  66. package/.docs/raw/docs/copilots/assistant-frame.mdx +19 -8
  67. package/.docs/raw/docs/guides/attachments.mdx +4 -4
  68. package/.docs/raw/docs/guides/branching.mdx +1 -1
  69. package/.docs/raw/docs/guides/chatgpt-subscription.mdx +1 -1
  70. package/.docs/raw/docs/guides/context-api.mdx +15 -17
  71. package/.docs/raw/docs/guides/dictation.mdx +2 -2
  72. package/.docs/raw/docs/guides/electron.mdx +1 -1
  73. package/.docs/raw/docs/guides/latex.mdx +1 -1
  74. package/.docs/raw/docs/guides/mentions.mdx +2 -0
  75. package/.docs/raw/docs/guides/message-timing.mdx +11 -5
  76. package/.docs/raw/docs/guides/quoting.mdx +1 -1
  77. package/.docs/raw/docs/guides/resumable-streams.mdx +3 -3
  78. package/.docs/raw/docs/guides/speech.mdx +1 -1
  79. package/.docs/raw/docs/guides/suggestions.mdx +8 -5
  80. package/.docs/raw/docs/guides/voice.mdx +1 -1
  81. package/.docs/raw/docs/ink/hooks.mdx +1 -1
  82. package/.docs/raw/docs/ink/index.mdx +3 -2
  83. package/.docs/raw/docs/ink/migration.mdx +1 -1
  84. package/.docs/raw/docs/ink/primitives.mdx +1 -1
  85. package/.docs/raw/docs/integrations/attachments/custom-adapter.mdx +3 -3
  86. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +3 -3
  87. package/.docs/raw/docs/integrations/frameworks/{cloudflare-agents/overview.mdx → cloudflare-agents.mdx} +4 -3
  88. package/.docs/raw/docs/integrations/frameworks/mastra/overview.mdx +1 -1
  89. package/.docs/raw/docs/integrations/frameworks/mastra/separate-server.mdx +1 -1
  90. package/.docs/raw/docs/integrations/index.mdx +2 -2
  91. package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +149 -131
  92. package/.docs/raw/docs/migrations/toolkit-tools.mdx +2 -2
  93. package/.docs/raw/docs/migrations/v0-15.mdx +34 -0
  94. package/.docs/raw/docs/primitives/action-bar.mdx +1 -1
  95. package/.docs/raw/docs/primitives/assistant-modal.mdx +1 -1
  96. package/.docs/raw/docs/primitives/attachment.mdx +1 -1
  97. package/.docs/raw/docs/primitives/branch-picker.mdx +1 -1
  98. package/.docs/raw/docs/primitives/chain-of-thought.mdx +3 -3
  99. package/.docs/raw/docs/primitives/composer.mdx +1 -1
  100. package/.docs/raw/docs/primitives/error.mdx +1 -1
  101. package/.docs/raw/docs/primitives/message.mdx +1 -1
  102. package/.docs/raw/docs/primitives/selection-toolbar.mdx +1 -1
  103. package/.docs/raw/docs/primitives/suggestion.mdx +4 -2
  104. package/.docs/raw/docs/primitives/thread-list.mdx +1 -1
  105. package/.docs/raw/docs/primitives/thread.mdx +2 -2
  106. package/.docs/raw/docs/react-native/adapters.mdx +1 -1
  107. package/.docs/raw/docs/react-native/index.mdx +2 -2
  108. package/.docs/raw/docs/react-native/migration.mdx +2 -2
  109. package/.docs/raw/docs/react-native/primitives.mdx +142 -5
  110. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +48 -6
  111. package/.docs/raw/docs/runtimes/ai-sdk/overview.mdx +3 -3
  112. package/.docs/raw/docs/runtimes/ai-sdk/v4-legacy.mdx +4 -4
  113. package/.docs/raw/docs/runtimes/ai-sdk/v7.mdx +31 -16
  114. package/.docs/raw/docs/runtimes/claude-managed-agents.mdx +118 -0
  115. package/.docs/raw/docs/runtimes/concepts/adapters.mdx +3 -3
  116. package/.docs/raw/docs/runtimes/concepts/architecture.mdx +3 -3
  117. package/.docs/raw/docs/runtimes/concepts/stability.mdx +2 -1
  118. package/.docs/raw/docs/runtimes/concepts/threads.mdx +73 -33
  119. package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +1 -1
  120. package/.docs/raw/docs/runtimes/custom/external-store.mdx +6 -2
  121. package/.docs/raw/docs/runtimes/langchain.mdx +2 -2
  122. package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +4 -0
  123. package/.docs/raw/docs/runtimes/opencode/quickstart.mdx +1 -1
  124. package/.docs/raw/docs/runtimes/pick-a-runtime.mdx +9 -2
  125. package/.docs/raw/docs/tools/backend.mdx +4 -4
  126. package/.docs/raw/docs/tools/defining-tools.mdx +21 -2
  127. package/.docs/raw/docs/tools/generative-ui-primitive.mdx +180 -0
  128. package/.docs/raw/docs/tools/generative-ui-slack.mdx +167 -0
  129. package/.docs/raw/docs/tools/generative-ui-teams.mdx +160 -0
  130. package/.docs/raw/docs/tools/generative-ui.mdx +224 -211
  131. package/.docs/raw/docs/tools/index.mdx +2 -1
  132. package/.docs/raw/docs/tools/interactables.mdx +8 -7
  133. package/.docs/raw/docs/tools/mcp-apps.mdx +18 -1
  134. package/.docs/raw/docs/tools/mcp.mdx +2 -2
  135. package/.docs/raw/docs/tools/openui.mdx +175 -0
  136. package/.docs/raw/docs/tools/tool-ui.mdx +18 -7
  137. package/.docs/raw/docs/tools/user-managed-mcp.mdx +7 -3
  138. package/.docs/raw/docs/ui/assistant-modal.mdx +3 -3
  139. package/.docs/raw/docs/ui/assistant-sidebar.mdx +1 -1
  140. package/.docs/raw/docs/ui/attachment.mdx +50 -3
  141. package/.docs/raw/docs/ui/composer-trigger-popover.mdx +36 -1
  142. package/.docs/raw/docs/ui/context-display.mdx +1 -1
  143. package/.docs/raw/docs/ui/directive-text.mdx +1 -1
  144. package/.docs/raw/docs/ui/file.mdx +2 -2
  145. package/.docs/raw/docs/ui/follow-up-suggestions.mdx +1 -1
  146. package/.docs/raw/docs/ui/image.mdx +2 -2
  147. package/.docs/raw/docs/ui/markdown.mdx +40 -1
  148. package/.docs/raw/docs/ui/mermaid.mdx +1 -1
  149. package/.docs/raw/docs/ui/message-timing.mdx +1 -1
  150. package/.docs/raw/docs/ui/model-selector.mdx +4 -4
  151. package/.docs/raw/docs/ui/part-grouping.mdx +1 -1
  152. package/.docs/raw/docs/ui/quote.mdx +3 -3
  153. package/.docs/raw/docs/ui/reasoning.mdx +31 -3
  154. package/.docs/raw/docs/ui/scrollbar.mdx +1 -1
  155. package/.docs/raw/docs/ui/sources.mdx +10 -1
  156. package/.docs/raw/docs/ui/streamdown.mdx +2 -2
  157. package/.docs/raw/docs/ui/syntax-highlighting.mdx +1 -1
  158. package/.docs/raw/docs/ui/thread-list.mdx +40 -1
  159. package/.docs/raw/docs/ui/thread.mdx +49 -2
  160. package/.docs/raw/docs/ui/tool-fallback.mdx +23 -9
  161. package/.docs/raw/docs/ui/tool-group.mdx +1 -1
  162. package/.docs/raw/docs/ui/voice.mdx +1 -1
  163. package/.docs/raw/docs/utilities/react-o11y.mdx +2 -2
  164. package/dist/xulux/catalog-client.d.ts.map +1 -1
  165. package/dist/xulux/catalog-client.js +51 -6
  166. package/dist/xulux/catalog-client.js.map +1 -1
  167. package/dist/xulux/types.d.ts +7 -7
  168. package/dist/xulux/types.d.ts.map +1 -1
  169. package/dist/xulux/types.js.map +1 -1
  170. package/package.json +5 -5
  171. package/src/tools/tests/docs.test.ts +10 -7
  172. package/src/tools/tests/path-traversal.test.ts +5 -2
  173. package/src/tools/tests/xulux-templates.test.ts +63 -0
  174. package/src/xulux/catalog-client.ts +68 -23
  175. package/src/xulux/types.ts +17 -13
  176. package/.docs/raw/docs/tools/interactables-legacy.mdx +0 -423
  177. package/.docs/raw/docs/ui/accordion.mdx +0 -266
  178. package/.docs/raw/docs/ui/badge.mdx +0 -150
  179. package/.docs/raw/docs/ui/diff-viewer.mdx +0 -280
  180. package/.docs/raw/docs/ui/dot-matrix.mdx +0 -133
  181. package/.docs/raw/docs/ui/number-roll.mdx +0 -154
  182. package/.docs/raw/docs/ui/select.mdx +0 -254
  183. package/.docs/raw/docs/ui/tabs.mdx +0 -271
  184. /package/.docs/raw/docs/{(docs) → (getting-started)}/architecture.mdx +0 -0
  185. /package/.docs/raw/docs/{(docs) → (getting-started)}/base-ui.mdx +0 -0
  186. /package/.docs/raw/docs/{(docs) → (getting-started)}/llm.mdx +0 -0
  187. /package/.docs/raw/docs/{(docs) → (getting-started)}/rtl.mdx +0 -0
@@ -4,7 +4,7 @@ description: Let users select and quote text from messages with a floating toolb
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
7
- import { QuoteSample } from "@/components/docs/samples/quote";
7
+ import { QuoteSample } from "@/components/pages/docs/samples/quote";
8
8
 
9
9
  <QuoteSample />
10
10
 
@@ -97,7 +97,7 @@ Quote data is stored in message metadata, **not** in message content. Use `injec
97
97
 
98
98
  ```typescript title="app/api/chat/route.ts" {2,9}
99
99
  import { convertToModelMessages, streamText } from "ai";
100
- import { injectQuoteContext } from "@assistant-ui/react-ai-sdk";
100
+ import { injectQuoteContext } from "@assistant-ui/ai-sdk";
101
101
 
102
102
  export async function POST(req: Request) {
103
103
  const { messages } = await req.json();
@@ -180,7 +180,7 @@ Quote preview inside the composer. Only renders when a quote is set.
180
180
  ### `injectQuoteContext`
181
181
 
182
182
  ```typescript
183
- import { injectQuoteContext } from "@assistant-ui/react-ai-sdk";
183
+ import { injectQuoteContext } from "@assistant-ui/ai-sdk";
184
184
 
185
185
  injectQuoteContext(messages: UIMessage[]): UIMessage[]
186
186
  ```
@@ -4,7 +4,10 @@ description: Collapsible UI for displaying AI reasoning and thinking messages.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
7
- import { ReasoningSample, ReasoningGroupSample } from "@/components/docs/samples/reasoning";
7
+ import { ReasoningSample, ReasoningStreamingSample } from "@/components/pages/docs/samples/reasoning";
8
+ import { ReasoningCompletedSample } from "@/components/pages/docs/samples/reasoning/completed-with-duration";
9
+ import { ReasoningLongSample } from "@/components/pages/docs/samples/reasoning/long-reasoning";
10
+ import { ReasoningVariantsSample } from "@/components/pages/docs/samples/reasoning/variant-showcase";
8
11
 
9
12
  <ReasoningSample />
10
13
 
@@ -115,12 +118,36 @@ Use the `variant` prop on `ReasoningRoot` to change the visual style:
115
118
  | `ghost` | No additional styling |
116
119
  | `muted` | Muted background |
117
120
 
121
+ ## Examples
122
+
123
+ ### Variant Showcase
124
+
125
+ Each variant renders in its closed and open state side by side. Select a trigger to toggle that disclosure.
126
+
127
+ <ReasoningVariantsSample />
128
+
129
+ ### Streaming Reasoning
130
+
131
+ The response shows partial reasoning and stays active. Select Stop to cancel the response and return the composer to its idle state.
132
+
133
+ <ReasoningStreamingSample />
134
+
135
+ ### Completed with Duration
136
+
137
+ Set `duration` in seconds on `ReasoningTrigger` to show the completed reasoning time in the trigger label. The disclosure starts closed because `defaultOpen` is `false`. Select the trigger to open or close the reasoning text.
138
+
139
+ <ReasoningCompletedSample />
140
+
141
+ ### Long Reasoning
142
+
143
+ The `defaultOpen` prop opens the disclosure when the page loads. `ReasoningText` holds long reasoning in a `max-h-64` scroll area. Scroll the text. Then collapse and expand the disclosure.
144
+
145
+ <ReasoningLongSample />
146
+
118
147
  ## Legacy ReasoningGroup
119
148
 
120
149
  `ReasoningGroup` is kept for existing code that still uses the deprecated `components.ReasoningGroup` prop on `MessagePrimitive.Parts`. New code should use `MessagePrimitive.GroupedParts` and compose the root/trigger/content pieces directly.
121
150
 
122
- <ReasoningGroupSample />
123
-
124
151
  ```tsx
125
152
  import { ReasoningGroup } from "@/components/assistant-ui/reasoning";
126
153
 
@@ -149,6 +176,7 @@ const ReasoningGroupImpl: ReasoningGroupComponent = ({
149
176
  };
150
177
  ```
151
178
 
179
+
152
180
  ## API Reference
153
181
 
154
182
  ### Composable API
@@ -4,7 +4,7 @@ description: Replace the default scrollbar with a custom Radix UI scroll area.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
7
- import { ScrollbarSample } from "@/components/docs/samples/scrollbar";
7
+ import { ScrollbarSample } from "@/components/pages/docs/samples/scrollbar";
8
8
 
9
9
  <ScrollbarSample />
10
10
 
@@ -4,7 +4,8 @@ description: Display URL sources with favicon, title, and external link.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
7
- import { SourcesSample } from "@/components/docs/samples/sources";
7
+ import { SourcesSample } from "@/components/pages/docs/samples/sources";
8
+ import { SourcesUrlSample } from "@/components/pages/docs/samples/sources/url-sources";
8
9
 
9
10
  <SourcesSample />
10
11
 
@@ -69,6 +70,14 @@ Use the `size` prop to change the size.
69
70
  <Source size="lg" /> // Large
70
71
  ```
71
72
 
73
+ ## Examples
74
+
75
+ ### URL Sources
76
+
77
+ One source shows its supplied title. The other source uses its domain because its title is absent.
78
+
79
+ <SourcesUrlSample />
80
+
72
81
  ## API Reference
73
82
 
74
83
  ### `Sources`
@@ -7,8 +7,8 @@ links:
7
7
  platforms: ["react"]
8
8
  ---
9
9
 
10
- import { PackageManagerTabs } from "@/components/docs/fumadocs/install/package-manager-tabs";
11
- import { StreamdownSample } from "@/components/docs/samples/streamdown";
10
+ import { PackageManagerTabs } from "@/components/pages/docs/fumadocs/install/package-manager-tabs";
11
+ import { StreamdownSample } from "@/components/pages/docs/samples/streamdown";
12
12
 
13
13
  <StreamdownSample />
14
14
 
@@ -4,7 +4,7 @@ description: Code block syntax highlighting with react-shiki or react-syntax-hig
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
7
- import { SyntaxHighlightingSample } from "@/components/docs/samples/syntax-highlighting";
7
+ import { SyntaxHighlightingSample } from "@/components/pages/docs/samples/syntax-highlighting";
8
8
 
9
9
  <Callout type="warn">Syntax highlighting is not enabled in markdown by default.</Callout>
10
10
 
@@ -4,7 +4,12 @@ description: Sidebar or dropdown component for switching between AI chat convers
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
7
- import { ThreadListSample } from "@/components/docs/samples/threadlist";
7
+ import { ThreadListSample } from "@/components/pages/docs/samples/threadlist";
8
+ import { PreviewCode } from "@/components/pages/docs/preview-code.server";
9
+ import { ThreadListSidebarSample } from "@/components/pages/docs/samples/thread-list/sidebar-composition";
10
+ import { ThreadListActiveSample } from "@/components/pages/docs/samples/thread-list/active-threads";
11
+ import { ThreadListNewSample } from "@/components/pages/docs/samples/thread-list/new-thread";
12
+ import { ThreadListArchiveSample } from "@/components/pages/docs/samples/thread-list/archive-thread";
8
13
 
9
14
  <ThreadListSample />
10
15
 
@@ -104,6 +109,40 @@ import { ThreadListPrimitive, ThreadListItemPrimitive } from "@assistant-ui/reac
104
109
  </ThreadListPrimitive.Root>
105
110
  ```
106
111
 
112
+ ## Examples
113
+
114
+ ### Active Threads
115
+
116
+ Select a different seeded conversation, or use the search field to filter the threads by title.
117
+
118
+ <PreviewCode file="components/pages/docs/samples/thread-list/active-threads" name="ActiveThreadList">
119
+ <ThreadListActiveSample />
120
+ </PreviewCode>
121
+
122
+ ### New Thread
123
+
124
+ The list starts empty, thus only the New Thread button shows. Click New Thread to make an active thread. The search field shows when a thread exists.
125
+
126
+ <PreviewCode file="components/pages/docs/samples/thread-list/new-thread" name="EmptyThreadList">
127
+ <ThreadListNewSample />
128
+ </PreviewCode>
129
+
130
+ ### Sidebar Composition
131
+
132
+ `ThreadListSidebar` wraps the same `ThreadList` in a complete sidebar shell.
133
+
134
+ <PreviewCode file="components/pages/docs/samples/thread-list/sidebar-composition" name="ThreadListSidebarDemo" className="p-0">
135
+ <ThreadListSidebarSample />
136
+ </PreviewCode>
137
+
138
+ ### Archive a Thread
139
+
140
+ Open the More menu of the active thread, then select Archive. The `onArchive` callback moves the thread to the archived list. Select Restore (`ThreadListItemPrimitive.Unarchive`) to move the thread back to the regular list.
141
+
142
+ <PreviewCode file="components/pages/docs/samples/thread-list/archive-thread" name="ArchivableThreadList">
143
+ <ThreadListArchiveSample />
144
+ </PreviewCode>
145
+
107
146
  ## API Reference
108
147
 
109
148
  ### ThreadListPrimitive.Root
@@ -4,7 +4,13 @@ description: Stream-ready React chat container with message list, composer, auto
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
7
- import { ThreadSample } from "@/components/docs/samples/thread";
7
+ import { ThreadSample } from "@/components/pages/docs/samples/thread";
8
+ import { ThreadHistorySample } from "@/components/pages/docs/samples/thread/thread-history";
9
+ import { ThreadActionsSample } from "@/components/pages/docs/samples/thread/message-actions";
10
+ import { PreviewCode } from "@/components/pages/docs/preview-code.server";
11
+ import { ThreadWelcomeSuggestionsSample } from "@/components/pages/docs/samples/thread/welcome-with-suggestions";
12
+ import { ThreadBranchSample } from "@/components/pages/docs/samples/thread/branching-response";
13
+ import { ThreadRunningSample } from "@/components/pages/docs/samples/thread/running-response";
8
14
 
9
15
  A complete chat interface that combines message rendering, auto-scrolling, composer input,
10
16
  attachments, and conditional UI states. Fully customizable and composable.
@@ -90,6 +96,13 @@ export default function Chat() {
90
96
  </AuiIf>
91
97
  ```
92
98
 
99
+ ### Thread with History
100
+
101
+ The thread shows a completed multi-turn conversation. The composer stays below the
102
+ messages, ready for the next input.
103
+
104
+ <ThreadHistorySample />
105
+
93
106
  ### Conditional Send/Cancel Button
94
107
 
95
108
  ```tsx
@@ -106,10 +119,23 @@ export default function Chat() {
106
119
  </AuiIf>
107
120
  ```
108
121
 
122
+ While the last assistant response runs, the composer shows the cancel action, not the send action, and the action bar of the response stays hidden. Click the stop button to cancel the run. The composer then shows the send action again.
123
+
124
+ <ThreadRunningSample />
125
+
109
126
  ### Suggestions
110
127
 
111
128
  Display suggested prompts using the Suggestions API. See the [Suggestions guide](/docs/guides/suggestions) for detailed configuration.
112
129
 
130
+ An empty thread centers the welcome screen and shows the configured suggestion chips. When you select a chip, the thread sends its prompt.
131
+
132
+ <PreviewCode
133
+ file="components/pages/docs/samples/thread/welcome-with-suggestions"
134
+ name="ChatWithSuggestions"
135
+ >
136
+ <ThreadWelcomeSuggestionsSample />
137
+ </PreviewCode>
138
+
113
139
  ```tsx
114
140
  import type { ReactNode } from "react";
115
141
  import {
@@ -119,7 +145,7 @@ import {
119
145
  Suggestions,
120
146
  ThreadPrimitive,
121
147
  } from "@assistant-ui/react";
122
- import { useChatRuntime } from "@assistant-ui/react-ai-sdk";
148
+ import { useChatRuntime } from "@assistant-ui/ai-sdk";
123
149
 
124
150
  // Configure suggestions in your runtime provider
125
151
  const config = AuiConfig({
@@ -152,6 +178,27 @@ const SuggestionItem = () => (
152
178
  );
153
179
  ```
154
180
 
181
+ ### Branching Response
182
+
183
+ Select the refresh action below the assistant response to make an alternate branch. The built-in branch picker then shows `2 / 2` with arrows that switch between the two branches.
184
+
185
+ <PreviewCode
186
+ file="components/pages/docs/samples/thread/branching-response"
187
+ name="Chat"
188
+ >
189
+ <ThreadBranchSample />
190
+ </PreviewCode>
191
+
192
+ ### Message Actions
193
+
194
+ Hover over the first assistant response to show its action bar. When the thread is idle, the last response always shows its actions. The copied `Thread` component sets `hideWhenRunning` and `autohide="not-last"` on `ActionBarPrimitive.Root`. Refer to the [ActionBar primitive](/docs/primitives/action-bar) to change this behavior.
195
+
196
+ <ThreadActionsSample />
197
+
198
+ ## Composer Focus
199
+
200
+ Set `autoFocus={false}` to keep the page focus. This setting stops composer focus when the thread mounts, starts a run, changes threads, or scrolls to the bottom. The default value is `true`.
201
+
155
202
  ## Component Overrides
156
203
 
157
204
  `Thread` accepts an optional `components` prop that swaps parts of the rendering without editing the copied file. All slots are optional; omitted slots keep the built-in rendering.
@@ -6,11 +6,13 @@ platforms: ["react"]
6
6
 
7
7
  import {
8
8
  ToolFallbackSample,
9
- ToolFallbackRunningSample,
9
+ ToolFallbackCompletedSample,
10
10
  ToolFallbackCancelledSample,
11
11
  ToolFallbackStreamingSample,
12
- ToolFallbackRequiresActionSample,
13
- } from "@/components/docs/samples/tool-fallback";
12
+ } from "@/components/pages/docs/samples/tool-fallback";
13
+ import { PreviewCode } from "@/components/pages/docs/preview-code.server";
14
+ import { ToolFallbackApprovalSample } from "@/components/pages/docs/samples/tool-fallback/approval";
15
+ import { ToolFallbackErrorSample } from "@/components/pages/docs/samples/tool-fallback/failed-with-error";
14
16
 
15
17
  <ToolFallbackSample />
16
18
 
@@ -60,23 +62,34 @@ Interactive demo showing the full tool call lifecycle: running → complete.
60
62
 
61
63
  <ToolFallbackStreamingSample />
62
64
 
63
- ### Running State
65
+ ### Completed With Result
64
66
 
65
- Shows a loading spinner and shimmer animation while the tool is executing.
67
+ Shows the arguments and the structured result for the completed call.
66
68
 
67
- <ToolFallbackRunningSample />
69
+ <ToolFallbackCompletedSample />
70
+
71
+ ### Failed With Error State
72
+
73
+ Shows a service error above its arguments.
74
+
75
+ <ToolFallbackErrorSample />
68
76
 
69
77
  ### Cancelled State
70
78
 
71
- Shows a muted appearance when a tool call was cancelled.
79
+ The "Cancelled tool" label has a line through it. The arguments are muted after you open the call.
72
80
 
73
81
  <ToolFallbackCancelledSample />
74
82
 
75
83
  ### Approval State
76
84
 
77
- Shows the default Allow / Deny buttons rendered when a tool call enters `requires-action`. A tool call whose approval gate is already decided renders no buttons. The block auto-expands so the decision is visible without a click. Edit your project's copy of `tool-fallback.tsx` to add trust escalation, edit-args, custom labels, or analytics hooks — the shadcn philosophy is you own the file.
85
+ Select Allow or Deny. The `resume` callback records the choice, removes the buttons, and shows the result. The block opens automatically for `requires-action`, so you can select a decision without an extra click. A tool call whose approval gate is decided shows no buttons. Edit your project's copy of `tool-fallback.tsx` to add trust escalation, edit-args, custom labels, or analytics hooks.
78
86
 
79
- <ToolFallbackRequiresActionSample />
87
+ <PreviewCode
88
+ file="components/pages/docs/samples/tool-fallback/approval"
89
+ name="ToolWithApproval"
90
+ >
91
+ <ToolFallbackApprovalSample />
92
+ </PreviewCode>
80
93
 
81
94
  ## Composable API
82
95
 
@@ -116,6 +129,7 @@ import {
116
129
  interrupt={interrupt}
117
130
  approval={approval}
118
131
  respondToApproval={respondToApproval}
132
+ status={status}
119
133
  />
120
134
  <ToolFallback.Result result={result} />
121
135
  </ToolFallback.Content>
@@ -7,7 +7,7 @@ platforms: ["react"]
7
7
  import {
8
8
  ToolGroupSample,
9
9
  ToolGroupStreamingSample,
10
- } from "@/components/docs/samples/tool-group";
10
+ } from "@/components/pages/docs/samples/tool-group";
11
11
 
12
12
  A wrapper component that groups consecutive tool calls together, displaying them in a collapsible container with auto-expand behavior during streaming.
13
13
 
@@ -4,7 +4,7 @@ description: Realtime voice session controls with connect, mute, and status indi
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
7
- import { VoiceSample, VoiceVariantsSample, VoiceStatesSample } from "@/components/docs/samples/voice";
7
+ import { VoiceSample, VoiceVariantsSample, VoiceStatesSample } from "@/components/pages/docs/samples/voice";
8
8
 
9
9
  A control bar for realtime bidirectional voice sessions with an animated orb indicator. Works with any `RealtimeVoiceAdapter` (LiveKit, ElevenLabs, etc.).
10
10
 
@@ -4,12 +4,12 @@ description: Headless primitives for visualizing observability spans as collapsi
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
7
- import { WaterfallSample } from "@/components/docs/samples/o11y/waterfall";
7
+ import { WaterfallSample } from "@/components/pages/docs/samples/o11y/waterfall";
8
8
  import {
9
9
  StatusSample,
10
10
  CollapseSample,
11
11
  StreamingSample,
12
- } from "@/components/docs/samples/o11y/capability-samples";
12
+ } from "@/components/pages/docs/samples/o11y/capability-samples";
13
13
 
14
14
  <Callout type="warn">
15
15
  `@assistant-ui/react-o11y` is experimental. The API may change without notice.
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-client.d.ts","names":[],"sources":["../../src/xulux/catalog-client.ts"],"mappings":";;cAIa;iBAKG;iBA0CA;;;;;;iBAoBM,mBAAmB,QAAQ"}
1
+ {"version":3,"file":"catalog-client.d.ts","names":[],"sources":["../../src/xulux/catalog-client.ts"],"mappings":";;cASa;iBAsDG;iBAiCA;;;;;;iBAoBM,mBAAmB,QAAQ"}
@@ -1,18 +1,63 @@
1
1
  import { logger } from "../utils/logger.js";
2
+ import "./types.js";
2
3
  import { FALLBACK_CATALOG, FALLBACK_NOTE } from "./fallback-catalog.js";
4
+ import { z } from "zod";
3
5
  //#region src/xulux/catalog-client.ts
4
6
  const DEFAULT_CATALOG_URL = "https://www.assistant-ui.com/api/xulux/mcp-catalog";
5
7
  const CATALOG_TTL_MS = 3e5;
8
+ const catalogUrlSchema = z.url();
9
+ const catalogVersionSchema = z.looseObject({
10
+ id: z.string(),
11
+ entryId: z.string(),
12
+ name: z.string(),
13
+ description: z.string(),
14
+ previewUrl: catalogUrlSchema,
15
+ downloadUrl: catalogUrlSchema
16
+ });
17
+ const catalogTemplateSchema = z.looseObject({
18
+ id: z.string(),
19
+ templateId: z.string(),
20
+ versionId: z.string().nullable(),
21
+ kind: z.enum(["template", "example"]),
22
+ name: z.string(),
23
+ summary: z.string(),
24
+ assistantPlacement: z.string(),
25
+ features: z.array(z.string()),
26
+ customizable: z.array(z.string()),
27
+ versions: z.array(catalogVersionSchema),
28
+ previewUrl: catalogUrlSchema.optional(),
29
+ downloadUrl: catalogUrlSchema.optional(),
30
+ sandboxBaseUrl: catalogUrlSchema.optional(),
31
+ configRoots: z.record(z.string(), z.unknown()).optional(),
32
+ rules: z.looseObject({
33
+ required: z.array(z.string()),
34
+ unsupported: z.array(z.string()).optional()
35
+ }).optional(),
36
+ tools: z.looseObject({
37
+ builtIn: z.array(z.unknown()),
38
+ customToolSupported: z.boolean(),
39
+ renderers: z.array(z.unknown())
40
+ }).optional()
41
+ });
42
+ const catalogSchema = z.looseObject({
43
+ version: z.literal(1),
44
+ generatedAt: z.string(),
45
+ docsOrigin: z.string(),
46
+ templates: z.array(catalogTemplateSchema)
47
+ });
6
48
  function getCatalogUrl() {
7
49
  return process.env.XULUX_CATALOG_URL?.trim() || "https://www.assistant-ui.com/api/xulux/mcp-catalog";
8
50
  }
9
51
  function validateCatalog(data) {
10
- if (!data || typeof data !== "object" || Array.isArray(data)) throw new Error("Catalog response is not a JSON object.");
11
- const catalog = data;
12
- if (catalog.version !== 1) throw new Error(`Unsupported catalog version: ${String(catalog.version)}. Expected 1.`);
13
- if (!Array.isArray(catalog.templates)) throw new Error("Catalog response has no templates array.");
14
- for (const template of catalog.templates) if (!template || typeof template !== "object" || typeof template.id !== "string" || typeof template.templateId !== "string" || template.kind !== "template" && template.kind !== "example") throw new Error("Catalog response contains a malformed template entry (missing id/templateId/kind).");
15
- return catalog;
52
+ const version = data?.version;
53
+ if (version !== void 0 && version !== 1) throw new Error(`Unsupported catalog version: ${String(version)}. Expected 1.`);
54
+ const result = catalogSchema.safeParse(data);
55
+ if (!result.success) {
56
+ const issue = result.error.issues[0];
57
+ const path = issue?.path.length ? ` at ${issue.path.join(".")}` : "";
58
+ throw new Error(`Catalog response is malformed${path}: ${issue?.message ?? "invalid catalog"}.`);
59
+ }
60
+ return result.data;
16
61
  }
17
62
  let cache = null;
18
63
  function clearCatalogCache() {
@@ -1 +1 @@
1
- {"version":3,"file":"catalog-client.js","names":[],"sources":["../../src/xulux/catalog-client.ts"],"sourcesContent":["import { logger } from \"../utils/logger.js\";\nimport { FALLBACK_CATALOG, FALLBACK_NOTE } from \"./fallback-catalog.js\";\nimport type { XuluxCatalog, XuluxCatalogResult } from \"./types.js\";\n\nexport const DEFAULT_CATALOG_URL =\n \"https://www.assistant-ui.com/api/xulux/mcp-catalog\";\n\nconst CATALOG_TTL_MS = 5 * 60 * 1000;\n\nexport function getCatalogUrl(): string {\n const override = process.env.XULUX_CATALOG_URL?.trim();\n return override || DEFAULT_CATALOG_URL;\n}\n\nfunction validateCatalog(data: unknown): XuluxCatalog {\n if (!data || typeof data !== \"object\" || Array.isArray(data)) {\n throw new Error(\"Catalog response is not a JSON object.\");\n }\n const catalog = data as XuluxCatalog;\n if (catalog.version !== 1) {\n throw new Error(\n `Unsupported catalog version: ${String(catalog.version)}. Expected 1.`,\n );\n }\n if (!Array.isArray(catalog.templates)) {\n throw new Error(\"Catalog response has no templates array.\");\n }\n for (const template of catalog.templates) {\n if (\n !template ||\n typeof template !== \"object\" ||\n typeof template.id !== \"string\" ||\n typeof template.templateId !== \"string\" ||\n (template.kind !== \"template\" && template.kind !== \"example\")\n ) {\n throw new Error(\n \"Catalog response contains a malformed template entry (missing id/templateId/kind).\",\n );\n }\n }\n return catalog;\n}\n\ninterface CacheEntry {\n catalog: XuluxCatalog;\n fetchedAt: number;\n url: string;\n}\n\nlet cache: CacheEntry | null = null;\n\nexport function clearCatalogCache(): void {\n cache = null;\n}\n\nasync function fetchCatalog(url: string): Promise<XuluxCatalog> {\n const res = await fetch(url, {\n headers: { Accept: \"application/json\" },\n });\n if (!res.ok) {\n throw new Error(`Catalog fetch failed: HTTP ${res.status}`);\n }\n const data: unknown = await res.json();\n return validateCatalog(data);\n}\n\n/**\n * Returns the assistant-ui template catalog. Uses an in-memory five-minute cache, and falls\n * back to a minimal bundled catalog (marked degraded) when the live fetch\n * fails and no cached copy exists.\n */\nexport async function getXuluxCatalog(): Promise<XuluxCatalogResult> {\n const url = getCatalogUrl();\n const now = Date.now();\n\n if (cache && cache.url === url && now - cache.fetchedAt < CATALOG_TTL_MS) {\n return { catalog: cache.catalog, degraded: false };\n }\n\n try {\n const catalog = await fetchCatalog(url);\n cache = { catalog, fetchedAt: now, url };\n return { catalog, degraded: false };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.warn(\n `assistant-ui template catalog fetch failed (${url}): ${message}`,\n );\n\n // Prefer a stale cached copy over the minimal fallback.\n if (cache && cache.url === url) {\n return {\n catalog: cache.catalog,\n degraded: true,\n degradedReason: `Live catalog refresh failed (${message}); using previously fetched catalog.`,\n };\n }\n\n return {\n catalog: FALLBACK_CATALOG,\n degraded: true,\n degradedReason: `${message} ${FALLBACK_NOTE}`,\n };\n }\n}\n"],"mappings":";;;AAIA,MAAa,sBACX;AAEF,MAAM,iBAAiB;AAEvB,SAAgB,gBAAwB;CAEtC,OADiB,QAAQ,IAAI,mBAAmB,KAAK,KAAA;AAEvD;AAEA,SAAS,gBAAgB,MAA6B;CACpD,IAAI,CAAC,QAAQ,OAAO,SAAS,YAAY,MAAM,QAAQ,IAAI,GACzD,MAAM,IAAI,MAAM,wCAAwC;CAE1D,MAAM,UAAU;CAChB,IAAI,QAAQ,YAAY,GACtB,MAAM,IAAI,MACR,gCAAgC,OAAO,QAAQ,OAAO,EAAE,cAC1D;CAEF,IAAI,CAAC,MAAM,QAAQ,QAAQ,SAAS,GAClC,MAAM,IAAI,MAAM,0CAA0C;CAE5D,KAAK,MAAM,YAAY,QAAQ,WAC7B,IACE,CAAC,YACD,OAAO,aAAa,YACpB,OAAO,SAAS,OAAO,YACvB,OAAO,SAAS,eAAe,YAC9B,SAAS,SAAS,cAAc,SAAS,SAAS,WAEnD,MAAM,IAAI,MACR,oFACF;CAGJ,OAAO;AACT;AAQA,IAAI,QAA2B;AAE/B,SAAgB,oBAA0B;CACxC,QAAQ;AACV;AAEA,eAAe,aAAa,KAAoC;CAC9D,MAAM,MAAM,MAAM,MAAM,KAAK,EAC3B,SAAS,EAAE,QAAQ,mBAAmB,EACxC,CAAC;CACD,IAAI,CAAC,IAAI,IACP,MAAM,IAAI,MAAM,8BAA8B,IAAI,QAAQ;CAG5D,OAAO,gBAAgB,MADK,IAAI,KAAK,CACV;AAC7B;;;;;;AAOA,eAAsB,kBAA+C;CACnE,MAAM,MAAM,cAAc;CAC1B,MAAM,MAAM,KAAK,IAAI;CAErB,IAAI,SAAS,MAAM,QAAQ,OAAO,MAAM,MAAM,YAAY,gBACxD,OAAO;EAAE,SAAS,MAAM;EAAS,UAAU;CAAM;CAGnD,IAAI;EACF,MAAM,UAAU,MAAM,aAAa,GAAG;EACtC,QAAQ;GAAE;GAAS,WAAW;GAAK;EAAI;EACvC,OAAO;GAAE;GAAS,UAAU;EAAM;CACpC,SAAS,OAAO;EACd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACrE,OAAO,KACL,+CAA+C,IAAI,KAAK,SAC1D;EAGA,IAAI,SAAS,MAAM,QAAQ,KACzB,OAAO;GACL,SAAS,MAAM;GACf,UAAU;GACV,gBAAgB,gCAAgC,QAAQ;EAC1D;EAGF,OAAO;GACL,SAAS;GACT,UAAU;GACV,gBAAgB,GAAG,QAAQ,GAAG;EAChC;CACF;AACF"}
1
+ {"version":3,"file":"catalog-client.js","names":[],"sources":["../../src/xulux/catalog-client.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { logger } from \"../utils/logger.js\";\nimport { FALLBACK_CATALOG, FALLBACK_NOTE } from \"./fallback-catalog.js\";\nimport {\n XULUX_MCP_CATALOG_VERSION,\n type XuluxCatalog,\n type XuluxCatalogResult,\n} from \"./types.js\";\n\nexport const DEFAULT_CATALOG_URL =\n \"https://www.assistant-ui.com/api/xulux/mcp-catalog\";\n\nconst CATALOG_TTL_MS = 5 * 60 * 1000;\nconst catalogUrlSchema = z.url();\n\nconst catalogVersionSchema = z.looseObject({\n id: z.string(),\n entryId: z.string(),\n name: z.string(),\n description: z.string(),\n previewUrl: catalogUrlSchema,\n downloadUrl: catalogUrlSchema,\n});\n\nconst catalogTemplateSchema = z.looseObject({\n id: z.string(),\n templateId: z.string(),\n versionId: z.string().nullable(),\n kind: z.enum([\"template\", \"example\"]),\n name: z.string(),\n summary: z.string(),\n assistantPlacement: z.string(),\n features: z.array(z.string()),\n customizable: z.array(z.string()),\n versions: z.array(catalogVersionSchema),\n previewUrl: catalogUrlSchema.optional(),\n downloadUrl: catalogUrlSchema.optional(),\n sandboxBaseUrl: catalogUrlSchema.optional(),\n configRoots: z.record(z.string(), z.unknown()).optional(),\n rules: z\n .looseObject({\n required: z.array(z.string()),\n unsupported: z.array(z.string()).optional(),\n })\n .optional(),\n tools: z\n .looseObject({\n builtIn: z.array(z.unknown()),\n customToolSupported: z.boolean(),\n renderers: z.array(z.unknown()),\n })\n .optional(),\n});\n\nconst catalogSchema = z.looseObject({\n version: z.literal(XULUX_MCP_CATALOG_VERSION),\n // Not read anywhere in the package; validated for shape only, so an unused\n // field cannot veto the whole catalog.\n generatedAt: z.string(),\n docsOrigin: z.string(),\n templates: z.array(catalogTemplateSchema),\n});\n\nexport function getCatalogUrl(): string {\n const override = process.env.XULUX_CATALOG_URL?.trim();\n return override || DEFAULT_CATALOG_URL;\n}\n\nfunction validateCatalog(data: unknown): XuluxCatalog {\n // Checked ahead of the schema so a catalog rollout reports its version\n // rather than reading as a malformed payload.\n const version = (data as { version?: unknown } | null)?.version;\n if (version !== undefined && version !== XULUX_MCP_CATALOG_VERSION) {\n throw new Error(\n `Unsupported catalog version: ${String(version)}. Expected ${XULUX_MCP_CATALOG_VERSION}.`,\n );\n }\n const result = catalogSchema.safeParse(data);\n if (!result.success) {\n const issue = result.error.issues[0];\n const path = issue?.path.length ? ` at ${issue.path.join(\".\")}` : \"\";\n throw new Error(\n `Catalog response is malformed${path}: ${issue?.message ?? \"invalid catalog\"}.`,\n );\n }\n return result.data;\n}\n\ninterface CacheEntry {\n catalog: XuluxCatalog;\n fetchedAt: number;\n url: string;\n}\n\nlet cache: CacheEntry | null = null;\n\nexport function clearCatalogCache(): void {\n cache = null;\n}\n\nasync function fetchCatalog(url: string): Promise<XuluxCatalog> {\n const res = await fetch(url, {\n headers: { Accept: \"application/json\" },\n });\n if (!res.ok) {\n throw new Error(`Catalog fetch failed: HTTP ${res.status}`);\n }\n const data: unknown = await res.json();\n return validateCatalog(data);\n}\n\n/**\n * Returns the assistant-ui template catalog. Uses an in-memory five-minute cache, and falls\n * back to a minimal bundled catalog (marked degraded) when the live fetch\n * fails and no cached copy exists.\n */\nexport async function getXuluxCatalog(): Promise<XuluxCatalogResult> {\n const url = getCatalogUrl();\n const now = Date.now();\n\n if (cache && cache.url === url && now - cache.fetchedAt < CATALOG_TTL_MS) {\n return { catalog: cache.catalog, degraded: false };\n }\n\n try {\n const catalog = await fetchCatalog(url);\n cache = { catalog, fetchedAt: now, url };\n return { catalog, degraded: false };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.warn(\n `assistant-ui template catalog fetch failed (${url}): ${message}`,\n );\n\n // Prefer a stale cached copy over the minimal fallback.\n if (cache && cache.url === url) {\n return {\n catalog: cache.catalog,\n degraded: true,\n degradedReason: `Live catalog refresh failed (${message}); using previously fetched catalog.`,\n };\n }\n\n return {\n catalog: FALLBACK_CATALOG,\n degraded: true,\n degradedReason: `${message} ${FALLBACK_NOTE}`,\n };\n }\n}\n"],"mappings":"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"}
@@ -19,19 +19,19 @@ interface XuluxCatalogTemplate {
19
19
  features: string[];
20
20
  customizable: string[];
21
21
  versions: XuluxCatalogVersion[];
22
- previewUrl?: string;
23
- downloadUrl?: string;
24
- sandboxBaseUrl?: string;
25
- configRoots?: Record<string, unknown>;
22
+ previewUrl?: string | undefined;
23
+ downloadUrl?: string | undefined;
24
+ sandboxBaseUrl?: string | undefined;
25
+ configRoots?: Record<string, unknown> | undefined;
26
26
  rules?: {
27
27
  required: string[];
28
- unsupported?: string[];
29
- };
28
+ unsupported?: string[] | undefined;
29
+ } | undefined;
30
30
  tools?: {
31
31
  builtIn: unknown[];
32
32
  customToolSupported: boolean;
33
33
  renderers: unknown[];
34
- };
34
+ } | undefined;
35
35
  }
36
36
  interface XuluxCatalog {
37
37
  version: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/xulux/types.ts"],"mappings":";cAIa;UAEI;EACf;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;EACV;EACA;EACA;EACA,cAAc;EACd;IACE;IACA;;EAEF;IACE;IACA;IACA;;;UAIa;EACf;EACA;EACA;EACA,WAAW;;UAGI;EACf,SAAS;;EAET;;EAEA;;UAGe;EACf;EACA"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../src/xulux/types.ts"],"mappings":";cAIa;UAEI;EACf;EACA;EACA;EACA;EACA;EACA;;UAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,UAAU;EACV;EACA;EACA;EACA,cAAc;EACd;IAEM;IACA;;EAGN;IAEM;IACA;IACA;;;UAKS;EACf;EACA;EACA;EACA,WAAW;;UAGI;EACf,SAAS;;EAET;;EAEA;;UAGe;EACf;EACA"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../src/xulux/types.ts"],"sourcesContent":["// MCP-safe assistant-ui template catalog types. These mirror the payload served by the docs\n// app at GET /api/xulux/mcp-catalog. The MCP package never imports docs-app\n// internals; the endpoint payload is the contract.\n\nexport const XULUX_MCP_CATALOG_VERSION = 1;\n\nexport interface XuluxCatalogVersion {\n id: string;\n entryId: string;\n name: string;\n description: string;\n previewUrl: string;\n downloadUrl: string;\n}\n\nexport interface XuluxCatalogTemplate {\n id: string;\n templateId: string;\n versionId: string | null;\n kind: \"template\" | \"example\";\n name: string;\n summary: string;\n assistantPlacement: string;\n features: string[];\n customizable: string[];\n versions: XuluxCatalogVersion[];\n previewUrl?: string;\n downloadUrl?: string;\n sandboxBaseUrl?: string;\n configRoots?: Record<string, unknown>;\n rules?: {\n required: string[];\n unsupported?: string[];\n };\n tools?: {\n builtIn: unknown[];\n customToolSupported: boolean;\n renderers: unknown[];\n };\n}\n\nexport interface XuluxCatalog {\n version: number;\n generatedAt: string;\n docsOrigin: string;\n templates: XuluxCatalogTemplate[];\n}\n\nexport interface XuluxCatalogResult {\n catalog: XuluxCatalog;\n /** True when the bundled fallback catalog was used instead of live data. */\n degraded: boolean;\n /** Present when the live fetch failed and the fallback was used. */\n degradedReason?: string;\n}\n\nexport interface XuluxCatalogError {\n error: string;\n hint?: string;\n}\n"],"mappings":";AAIA,MAAa,4BAA4B"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../src/xulux/types.ts"],"sourcesContent":["// MCP-safe assistant-ui template catalog types. These mirror the payload served by the docs\n// app at GET /api/xulux/mcp-catalog. The MCP package never imports docs-app\n// internals; the endpoint payload is the contract.\n\nexport const XULUX_MCP_CATALOG_VERSION = 1;\n\nexport interface XuluxCatalogVersion {\n id: string;\n entryId: string;\n name: string;\n description: string;\n previewUrl: string;\n downloadUrl: string;\n}\n\nexport interface XuluxCatalogTemplate {\n id: string;\n templateId: string;\n versionId: string | null;\n kind: \"template\" | \"example\";\n name: string;\n summary: string;\n assistantPlacement: string;\n features: string[];\n customizable: string[];\n versions: XuluxCatalogVersion[];\n previewUrl?: string | undefined;\n downloadUrl?: string | undefined;\n sandboxBaseUrl?: string | undefined;\n configRoots?: Record<string, unknown> | undefined;\n rules?:\n | {\n required: string[];\n unsupported?: string[] | undefined;\n }\n | undefined;\n tools?:\n | {\n builtIn: unknown[];\n customToolSupported: boolean;\n renderers: unknown[];\n }\n | undefined;\n}\n\nexport interface XuluxCatalog {\n version: number;\n generatedAt: string;\n docsOrigin: string;\n templates: XuluxCatalogTemplate[];\n}\n\nexport interface XuluxCatalogResult {\n catalog: XuluxCatalog;\n /** True when the bundled fallback catalog was used instead of live data. */\n degraded: boolean;\n /** Present when the live fetch failed and the fallback was used. */\n degradedReason?: string;\n}\n\nexport interface XuluxCatalogError {\n error: string;\n hint?: string;\n}\n"],"mappings":";AAIA,MAAa,4BAA4B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@assistant-ui/mcp-docs-server",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "MCP server for assistant-ui documentation and examples",
5
5
  "keywords": [
6
6
  "mcp",
@@ -37,11 +37,11 @@
37
37
  "zod": "^4.4.3"
38
38
  },
39
39
  "devDependencies": {
40
+ "@assistant-ui/x-buildutils": "0.0.24",
40
41
  "@modelcontextprotocol/core": "^2.0.0",
41
- "@types/node": "^26.1.2",
42
- "tsx": "^4.23.10",
43
- "vitest": "^4.1.10",
44
- "@assistant-ui/x-buildutils": "0.0.22"
42
+ "@types/node": "^26.2.0",
43
+ "tsx": "^4.23.12",
44
+ "vitest": "^4.1.11"
45
45
  },
46
46
  "publishConfig": {
47
47
  "access": "public",
@@ -28,17 +28,17 @@ describe("assistantUIDocs", () => {
28
28
  expect(result.path).toBe("/");
29
29
  expect(result.found).toBe(true);
30
30
  expect(result.type).toBe("directory");
31
- expect(result.directories).toContain("(docs)");
31
+ expect(result.directories).toContain("(getting-started)");
32
32
  expect(result.directories).toContain("(reference)");
33
33
  expect(result.directories).toContain("ui");
34
34
  });
35
35
 
36
36
  it("should retrieve specific documentation file", async () => {
37
37
  const result = await testContext.callTool("assistantUIDocs", {
38
- paths: ["(docs)/index"],
38
+ paths: ["(getting-started)/index"],
39
39
  });
40
40
 
41
- expect(result.path).toBe("(docs)/index");
41
+ expect(result.path).toBe("(getting-started)/index");
42
42
  expect(result.found).toBe(true);
43
43
  expect(result.type).toBe("file");
44
44
  expect(result.content).toBeDefined();
@@ -57,12 +57,15 @@ describe("assistantUIDocs", () => {
57
57
 
58
58
  it("should support multiple path requests", async () => {
59
59
  const result = await testContext.callTool("assistantUIDocs", {
60
- paths: ["(docs)/index", "(reference)/api-reference/primitives/thread"],
60
+ paths: [
61
+ "(getting-started)/index",
62
+ "(reference)/api-reference/primitives/thread",
63
+ ],
61
64
  });
62
65
 
63
66
  expect(result.results).toBeDefined();
64
67
  expect(result.results).toHaveLength(2);
65
- expect(result.results[0].path).toBe("(docs)/index");
68
+ expect(result.results[0].path).toBe("(getting-started)/index");
66
69
  expect(result.results[1].path).toBe(
67
70
  "(reference)/api-reference/primitives/thread",
68
71
  );
@@ -83,7 +86,7 @@ describe("assistantUIDocs", () => {
83
86
 
84
87
  it("should parse MDX files with frontmatter", async () => {
85
88
  const result = await testContext.callTool("assistantUIDocs", {
86
- paths: ["(docs)/index"],
89
+ paths: ["(getting-started)/index"],
87
90
  });
88
91
 
89
92
  expect(result.content).toBeDefined();
@@ -93,7 +96,7 @@ describe("assistantUIDocs", () => {
93
96
 
94
97
  it("includes title and excerpt on a file response", async () => {
95
98
  const result = await testContext.callTool("assistantUIDocs", {
96
- paths: ["(docs)/index"],
99
+ paths: ["(getting-started)/index"],
97
100
  });
98
101
  expect(result.type).toBe("file");
99
102
  expect(result.title ?? result.excerpt).toBeDefined();