@assistant-ui/mcp-docs-server 0.1.32 → 0.1.34

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 (134) hide show
  1. package/.docs/organized/code-examples/waterfall.md +20 -22
  2. package/.docs/organized/code-examples/with-a2a.md +24 -24
  3. package/.docs/organized/code-examples/with-ag-ui.md +30 -25
  4. package/.docs/organized/code-examples/with-ai-sdk-v6.md +11 -9
  5. package/.docs/organized/code-examples/with-artifacts.md +49 -37
  6. package/.docs/organized/code-examples/with-assistant-transport.md +63 -51
  7. package/.docs/organized/code-examples/with-browser-extension.md +22 -10
  8. package/.docs/organized/code-examples/with-chain-of-thought.md +406 -87
  9. package/.docs/organized/code-examples/with-cloud-standalone.md +25 -24
  10. package/.docs/organized/code-examples/with-cloud.md +11 -9
  11. package/.docs/organized/code-examples/with-custom-thread-list.md +14 -12
  12. package/.docs/organized/code-examples/with-elevenlabs-conversational.md +23 -21
  13. package/.docs/organized/code-examples/with-elevenlabs-scribe.md +14 -13
  14. package/.docs/organized/code-examples/with-expo.md +44 -29
  15. package/.docs/organized/code-examples/with-external-store.md +9 -7
  16. package/.docs/organized/code-examples/with-ffmpeg.md +322 -285
  17. package/.docs/organized/code-examples/with-generative-ui.md +1066 -256
  18. package/.docs/organized/code-examples/with-google-adk.md +10 -8
  19. package/.docs/organized/code-examples/with-heat-graph.md +13 -11
  20. package/.docs/organized/code-examples/with-image-generation.md +19 -17
  21. package/.docs/organized/code-examples/with-interactables.md +317 -239
  22. package/.docs/organized/code-examples/with-langchain.md +14 -12
  23. package/.docs/organized/code-examples/with-langgraph.md +91 -83
  24. package/.docs/organized/code-examples/with-livekit.md +24 -22
  25. package/.docs/organized/code-examples/with-mcp.md +18 -12
  26. package/.docs/organized/code-examples/with-opencode.md +66 -66
  27. package/.docs/organized/code-examples/with-react-hook-form.md +19 -17
  28. package/.docs/organized/code-examples/with-react-ink.md +297 -102
  29. package/.docs/organized/code-examples/with-react-router.md +17 -15
  30. package/.docs/organized/code-examples/with-resumable-stream.md +15 -14
  31. package/.docs/organized/code-examples/with-store.md +78 -76
  32. package/.docs/organized/code-examples/with-tanstack.md +13 -14
  33. package/.docs/organized/code-examples/with-tap-runtime.md +26 -24
  34. package/.docs/raw/docs/(docs)/architecture.mdx +94 -42
  35. package/.docs/raw/docs/(docs)/cli.mdx +1 -2
  36. package/.docs/raw/docs/(docs)/installation.mdx +1 -1
  37. package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +5 -1
  38. package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +15 -15
  39. package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +14 -1
  40. package/.docs/raw/docs/(reference)/api-reference/generative-ui/index.mdx +18 -0
  41. package/.docs/raw/docs/(reference)/api-reference/generative-ui/rendering.mdx +33 -0
  42. package/.docs/raw/docs/(reference)/api-reference/generative-ui/spec.mdx +45 -0
  43. package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +41 -41
  44. package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +19 -1
  45. package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +122 -122
  46. package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +43 -2
  47. package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +6 -0
  48. package/.docs/raw/docs/(reference)/api-reference/overview.mdx +4 -6
  49. package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +30 -0
  50. package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +20 -3
  51. package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +8 -8
  52. package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +52 -4
  53. package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +100 -10
  54. package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +7 -59
  55. package/.docs/raw/docs/cloud/ai-sdk.mdx +0 -2
  56. package/.docs/raw/docs/{(docs)/copilots → copilots}/model-context.mdx +34 -26
  57. package/.docs/raw/docs/{(docs)/copilots → copilots}/motivation.mdx +32 -26
  58. package/.docs/raw/docs/guides/chain-of-thought.mdx +7 -9
  59. package/.docs/raw/docs/guides/context-api.mdx +2 -1
  60. package/.docs/raw/docs/guides/index.mdx +3 -12
  61. package/.docs/raw/docs/guides/mentions.mdx +4 -4
  62. package/.docs/raw/docs/guides/slash-commands.mdx +1 -1
  63. package/.docs/raw/docs/guides/suggestions.mdx +1 -1
  64. package/.docs/raw/docs/ink/adapters.mdx +23 -1
  65. package/.docs/raw/docs/ink/hooks.mdx +101 -85
  66. package/.docs/raw/docs/ink/migration.mdx +1 -1
  67. package/.docs/raw/docs/ink/primitives.mdx +2 -2
  68. package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +1 -1
  69. package/.docs/raw/docs/integrations/index.mdx +2 -2
  70. package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +17 -2
  71. package/.docs/raw/docs/migrations/toolkit-tools.mdx +232 -0
  72. package/.docs/raw/docs/primitives/chain-of-thought.mdx +10 -16
  73. package/.docs/raw/docs/primitives/message.mdx +9 -10
  74. package/.docs/raw/docs/react-native/hooks.mdx +62 -79
  75. package/.docs/raw/docs/react-native/migration.mdx +1 -1
  76. package/.docs/raw/docs/react-native/primitives.mdx +2 -2
  77. package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +3 -0
  78. package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +41 -0
  79. package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +122 -1
  80. package/.docs/raw/docs/runtimes/concepts/architecture.mdx +46 -4
  81. package/.docs/raw/docs/runtimes/concepts/threads.mdx +7 -1
  82. package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +54 -12
  83. package/.docs/raw/docs/runtimes/custom/external-store.mdx +62 -4
  84. package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +30 -7
  85. package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +108 -38
  86. package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +2 -2
  87. package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +14 -1
  88. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +64 -50
  89. package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +98 -86
  90. package/.docs/raw/docs/tools/backend.mdx +144 -0
  91. package/.docs/raw/docs/tools/defining-tools.mdx +538 -0
  92. package/.docs/raw/docs/tools/dynamic-tools.mdx +110 -0
  93. package/.docs/raw/docs/tools/generative-ui.mdx +214 -0
  94. package/.docs/raw/docs/tools/index.mdx +71 -0
  95. package/.docs/raw/docs/{guides → tools}/interactables.mdx +1 -1
  96. package/.docs/raw/docs/{integrations/tools → tools}/mcp.mdx +145 -50
  97. package/.docs/raw/docs/{guides → tools}/multi-agent.mdx +15 -17
  98. package/.docs/raw/docs/tools/tool-ui.mdx +967 -0
  99. package/.docs/raw/docs/{integrations/tools/react-mcp.mdx → tools/user-managed-mcp.mdx} +7 -7
  100. package/.docs/raw/docs/ui/directive-text.mdx +3 -3
  101. package/.docs/raw/docs/ui/mcp-config.mdx +4 -4
  102. package/.docs/raw/docs/ui/mermaid.mdx +16 -9
  103. package/.docs/raw/docs/ui/part-grouping.mdx +84 -50
  104. package/.docs/raw/docs/ui/reasoning.mdx +4 -5
  105. package/.docs/raw/docs/ui/tool-fallback.mdx +16 -0
  106. package/.docs/raw/docs/ui/tool-group.mdx +5 -6
  107. package/.docs/raw/docs/utilities/heat-graph.mdx +1 -1
  108. package/.docs/raw/docs/utilities/react-o11y.mdx +2 -2
  109. package/dist/constants.js.map +1 -1
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js.map +1 -1
  112. package/dist/prepare-docs/code-examples.d.ts.map +1 -1
  113. package/dist/prepare-docs/code-examples.js.map +1 -1
  114. package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
  115. package/dist/prepare-docs/copy-raw.js.map +1 -1
  116. package/dist/prepare-docs/prepare.js.map +1 -1
  117. package/dist/stdio.js.map +1 -1
  118. package/dist/tools/docs.js.map +1 -1
  119. package/dist/tools/examples.js.map +1 -1
  120. package/dist/tools/tests/test-setup.js.map +1 -1
  121. package/dist/utils/mdx.js.map +1 -1
  122. package/dist/utils/paths.d.ts.map +1 -1
  123. package/dist/utils/paths.js.map +1 -1
  124. package/package.json +5 -5
  125. package/.docs/organized/code-examples/with-parent-id-grouping.md +0 -596
  126. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +0 -151
  127. package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +0 -230
  128. package/.docs/raw/docs/guides/generative-ui.mdx +0 -142
  129. package/.docs/raw/docs/guides/tool-ui.mdx +0 -858
  130. package/.docs/raw/docs/guides/tools.mdx +0 -736
  131. /package/.docs/raw/docs/{(docs)/copilots → copilots}/assistant-frame.mdx +0 -0
  132. /package/.docs/raw/docs/{(docs)/copilots → copilots}/make-assistant-visible.mdx +0 -0
  133. /package/.docs/raw/docs/{(docs)/copilots → copilots}/use-assistant-instructions.mdx +0 -0
  134. /package/.docs/raw/docs/{guides → tools}/mcp-apps.mdx +0 -0
@@ -3,7 +3,7 @@ title: User-managed MCP servers
3
3
  description: Let end users add and authenticate MCP servers from the browser with @assistant-ui/react-mcp.
4
4
  ---
5
5
 
6
- [`@assistant-ui/react-mcp`](https://npmjs.com/package/@assistant-ui/react-mcp) is the user-facing layer for MCP. Where the [server-side MCP guide](/docs/integrations/tools/mcp) wires a single fixed set of MCP servers into your API route, this package lets *end users* see a list of connectors, sign in via OAuth, paste a custom server URL, and have the resulting tool catalog flow into the chat — automatically.
6
+ [`@assistant-ui/react-mcp`](https://npmjs.com/package/@assistant-ui/react-mcp) is the user-facing layer for MCP. Where the [server-side MCP guide](/docs/tools/mcp) wires a single fixed set of MCP servers into your API route, this package lets *end users* see a list of connectors, sign in via OAuth, paste a custom server URL, and have the resulting tool catalog flow into the chat — automatically.
7
7
 
8
8
  Two ways a server reaches the user:
9
9
 
@@ -17,12 +17,12 @@ Both flow through one connection lifecycle, one persisted state surface, and one
17
17
  ```
18
18
  useAui({ mcp: McpManagerResource({ connectors }) })
19
19
  │
20
- ├─ Tap resource — connection lifecycle, server lookup, OAuth/bearer auth
20
+ ├─ Resource — connection lifecycle, server lookup, OAuth/bearer auth
21
21
  ├─ Auto-mounts the modelContext scope when no chat runtime provides one
22
22
  └─ Registers connected tools as frontend tools — your chat sees them automatically
23
23
  ```
24
24
 
25
- The manager is a single tap resource. Mount it with `useAui` like any other scope. OAuth (PKCE + RFC 7591 dynamic client registration), bearer, and "no auth" are first-class. Token refresh runs inside the MCP SDK on 401; this package mediates persistence and the redirect step.
25
+ The manager is a single resource. Mount it with `useAui` like any other scope. OAuth (PKCE + RFC 7591 dynamic client registration), bearer, and "no auth" are first-class. Token refresh runs inside the MCP SDK on 401; this package mediates persistence and the redirect step.
26
26
 
27
27
  ## Setup
28
28
 
@@ -221,7 +221,7 @@ Tool names are prefixed `serverId__toolName` to avoid collisions across connecte
221
221
  If no chat runtime is mounted, `McpManagerResource` brings its own minimal `modelContext` along. Tools are still callable directly:
222
222
 
223
223
  ```ts
224
- // In an event handler — never in render. See the tap conventions.
224
+ // In an event handler, never in render.
225
225
  const aui = useAui();
226
226
  const out = await aui.mcp().server({ id: "linear" }).callTool("search", { q });
227
227
  ```
@@ -293,7 +293,7 @@ const connectionState = useAuiState((s) => s.mcpServer.connectionState);
293
293
  // ^ requires McpServerByIdProvider
294
294
  ```
295
295
 
296
- Imperative methods — `useAui` + resolve in a callback (never during render — see the [tap skill](https://github.com/assistant-ui/assistant-ui/blob/main/.claude/skills/tap/SKILL.md) for why):
296
+ Imperative methods: `useAui` + resolve in a callback (never during render):
297
297
 
298
298
  ```ts
299
299
  const aui = useAui();
@@ -327,11 +327,11 @@ What's deferred:
327
327
  <Card
328
328
  title="Server-side MCP"
329
329
  description="App-developer-controlled MCP servers wired into the API route."
330
- href="/docs/integrations/tools/mcp"
330
+ href="/docs/tools/mcp"
331
331
  />
332
332
  <Card
333
333
  title="Tools and tool UI"
334
334
  description="Build custom renderers for tool calls and approvals."
335
- href="/docs/guides/tools"
335
+ href="/docs/tools/defining-tools"
336
336
  />
337
337
  </Cards>
@@ -49,7 +49,7 @@ Keep your markdown renderer (e.g. `MarkdownText`) for assistant messages — ass
49
49
 
50
50
  ```tsx
51
51
  import { createDirectiveText } from "@/components/assistant-ui/directive-text";
52
- import { unstable_defaultDirectiveFormatter } from "@assistant-ui/core";
52
+ import { unstable_defaultDirectiveFormatter } from "@assistant-ui/react";
53
53
  import { FileTextIcon, SparklesIcon, UserIcon, WrenchIcon } from "lucide-react";
54
54
 
55
55
  const DirectiveTextWithIcons = createDirectiveText(
@@ -74,7 +74,7 @@ A matching `iconMap` / `fallbackIcon` option is accepted by [`ComposerTriggerPop
74
74
  The default format is `:type[label]{name=id}`. For a different format, build a custom `Unstable_DirectiveFormatter` and wrap it with `createDirectiveText`:
75
75
 
76
76
  ```tsx
77
- import type { Unstable_DirectiveFormatter } from "@assistant-ui/core";
77
+ import type { Unstable_DirectiveFormatter } from "@assistant-ui/react";
78
78
  import { createDirectiveText } from "@/components/assistant-ui/directive-text";
79
79
 
80
80
  const slashFormatter: Unstable_DirectiveFormatter = {
@@ -97,7 +97,7 @@ Because `directive-text.tsx` is copied into your project, you can also edit it d
97
97
 
98
98
  ### `DirectiveText`
99
99
 
100
- A `TextMessagePartComponent` that parses `:type[label]{name=id}` directives and renders them as inline chips. Uses the default formatter from `@assistant-ui/core` and renders chips without icons. For per-type icons, build a component with `createDirectiveText(formatter, { iconMap })`.
100
+ A `TextMessagePartComponent` that parses `:type[label]{name=id}` directives and renders them as inline chips. Uses the default formatter from `@assistant-ui/react` and renders chips without icons. For per-type icons, build a component with `createDirectiveText(formatter, { iconMap })`.
101
101
 
102
102
  ### `createDirectiveText(formatter, options?)`
103
103
 
@@ -4,7 +4,7 @@ description: Drop-in shadcn dialog that lists MCP connectors and custom servers,
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
7
- `McpConfigDialog` is a shadcn template that wraps the [`@assistant-ui/react-mcp`](/docs/integrations/tools/react-mcp) primitives. Render it anywhere inside an `McpManagerResource`-mounted client and your users get a styled MCP server panel — no manual primitive composition.
7
+ `McpConfigDialog` is a shadcn template that wraps the [`@assistant-ui/react-mcp`](/docs/tools/user-managed-mcp) primitives. Render it anywhere inside an `McpManagerResource`-mounted client and your users get a styled MCP server panel — no manual primitive composition.
8
8
 
9
9
  ## Getting Started
10
10
 
@@ -81,7 +81,7 @@ Pass children to swap the default button for your own:
81
81
 
82
82
  ### Wire up the OAuth callback
83
83
 
84
- Required for any OAuth-enabled connector or custom server. See the [OAuth callback section in the react-mcp guide](/docs/integrations/tools/react-mcp#handle-the-oauth-callback) for the route handler.
84
+ Required for any OAuth-enabled connector or custom server. See the [OAuth callback section in the react-mcp guide](/docs/tools/user-managed-mcp#handle-the-oauth-callback) for the route handler.
85
85
 
86
86
  </Step>
87
87
  </Steps>
@@ -92,11 +92,11 @@ Required for any OAuth-enabled connector or custom server. See the [OAuth callba
92
92
  <Card
93
93
  title="User-managed MCP servers"
94
94
  description="Full @assistant-ui/react-mcp guide — connectors, custom servers, OAuth, storage, custom primitives."
95
- href="/docs/integrations/tools/react-mcp"
95
+ href="/docs/tools/user-managed-mcp"
96
96
  />
97
97
  <Card
98
98
  title="Server-side MCP"
99
99
  description="App-developer-controlled MCP servers wired into the API route."
100
- href="/docs/integrations/tools/mcp"
100
+ href="/docs/tools/mcp"
101
101
  />
102
102
  </Cards>
@@ -50,34 +50,41 @@ export const MarkdownText = memo(MarkdownTextImpl);
50
50
 
51
51
  ## Configuration
52
52
 
53
- Configure mermaid options in `mermaid-diagram.tsx`:
53
+ Configure rendering options in `mermaid-diagram.tsx`:
54
54
 
55
55
  ```tsx title="/components/assistant-ui/mermaid-diagram.tsx"
56
- mermaid.initialize({ theme: "default" });
56
+ renderMermaidSVG(code, {
57
+ bg: "var(--background)",
58
+ fg: "var(--foreground)",
59
+ muted: "var(--muted-foreground)",
60
+ border: "var(--border)",
61
+ accent: "var(--foreground)",
62
+ transparent: true,
63
+ });
57
64
  ```
58
65
 
66
+ The palette follows your theme's background, foreground, and shadcn color tokens, so diagrams match light and dark mode automatically.
67
+
59
68
  ## Streaming Performance
60
69
 
61
70
  The `MermaidDiagram` component is optimized for streaming scenarios:
62
71
 
63
- - **Smart completion detection**: Only renders when the specific code block is complete
64
- - **Zero failed renders**: Avoids parsing incomplete diagram code during streaming
72
+ - **Skeleton while streaming**: Shows a placeholder skeleton until the response finishes streaming, then renders the diagram synchronously
73
+ - **Raw source fallback**: Invalid or unsupported diagrams fall back to displaying the raw source
65
74
 
66
75
 
67
76
  ## Supported Diagram Types
68
77
 
69
- Mermaid supports various diagram types including:
78
+ The component renders these diagram types:
70
79
 
71
80
  - Flowcharts and decision trees
72
81
  - Sequence diagrams
73
- - Gantt charts
74
82
  - Class diagrams
75
83
  - State diagrams
76
- - Git graphs
77
- - User journey maps
78
84
  - Entity relationship diagrams
85
+ - XY charts (bar, line, combined)
79
86
 
80
- See the [Mermaid documentation](https://mermaid.js.org/) for complete syntax reference.
87
+ Other mermaid diagram types fall back to displaying the raw source. See the [Mermaid documentation](https://mermaid.js.org/) for syntax reference.
81
88
 
82
89
  ## Related Components
83
90
 
@@ -10,18 +10,19 @@ import { PartGroupingSample } from "@/components/docs/samples/part-grouping";
10
10
 
11
11
  ## Basic Usage
12
12
 
13
- For adjacent grouping, use `MessagePrimitive.GroupedParts`. Return a group-key path for each part; adjacent parts that share a group key are coalesced and rendered through the group case.
13
+ For adjacent grouping, use `MessagePrimitive.GroupedParts`. For the common case — grouping by `part.type` — pass `groupPartByType` to map each part type to a group-key path. Adjacent parts that share a group key are coalesced and rendered through the group case.
14
14
 
15
15
  ```tsx title="/components/assistant-ui/thread.tsx"
16
+ import { MessagePrimitive, groupPartByType } from "@assistant-ui/react";
17
+
16
18
  const AssistantMessage: FC = () => {
17
19
  return (
18
20
  <MessagePrimitive.Root className="...">
19
21
  <div className="...">
20
22
  <MessagePrimitive.GroupedParts
21
- groupBy={(part) => {
22
- if (part.type === "tool-call") return ["group-tool"];
23
- return null;
24
- }}
23
+ groupBy={groupPartByType({
24
+ "tool-call": ["group-tool"],
25
+ })}
25
26
  >
26
27
  {({ part, children }) => {
27
28
  switch (part.type) {
@@ -42,6 +43,8 @@ const AssistantMessage: FC = () => {
42
43
  };
43
44
  ```
44
45
 
46
+ Reach for an inline `groupBy={(part) => …}` only when the helper isn't expressive enough — e.g. you need to branch on `part.toolName`, `part.parentId`, or part metadata.
47
+
45
48
  ## How Adjacent Grouping Works
46
49
 
47
50
  `groupBy` receives each part and returns either `null` for an ungrouped leaf or a group-key path such as `["group-chainOfThought", "group-tool"]`. Group keys must start with `"group-"` so your render function can distinguish synthetic groups from real part types.
@@ -89,7 +92,7 @@ function ParentGroup({
89
92
 
90
93
  <MessagePrimitive.GroupedParts
91
94
  groupBy={(part) => {
92
- if (!part.parentId) return null;
95
+ if (!part.parentId) return [];
93
96
  return [`group-parent-${part.parentId}`];
94
97
  }}
95
98
  >
@@ -117,7 +120,7 @@ Organize adjacent tool calls by tool name:
117
120
  ```tsx
118
121
  <MessagePrimitive.GroupedParts
119
122
  groupBy={(part) => {
120
- if (part.type !== "tool-call") return null;
123
+ if (part.type !== "tool-call") return [];
121
124
  return [`group-tool-${part.toolName}`];
122
125
  }}
123
126
  >
@@ -147,10 +150,9 @@ Combine multiple text parts into cohesive blocks:
147
150
 
148
151
  ```tsx
149
152
  <MessagePrimitive.GroupedParts
150
- groupBy={(part) => {
151
- if (part.type === "text") return ["group-text-block"];
152
- return null;
153
- }}
153
+ groupBy={groupPartByType({
154
+ text: ["group-text-block"],
155
+ })}
154
156
  >
155
157
  {({ part, children }) => {
156
158
  switch (part.type) {
@@ -177,12 +179,11 @@ Separate different types of content for distinct visual treatment:
177
179
 
178
180
  ```tsx
179
181
  <MessagePrimitive.GroupedParts
180
- groupBy={(part) => {
181
- if (part.type === "text") return ["group-content-text"];
182
- if (part.type === "tool-call") return ["group-content-tools"];
183
- if (part.type === "reasoning") return ["group-content-reasoning"];
184
- return null;
185
- }}
182
+ groupBy={groupPartByType({
183
+ text: ["group-content-text"],
184
+ "tool-call": ["group-content-tools"],
185
+ reasoning: ["group-content-reasoning"],
186
+ })}
186
187
  >
187
188
  {({ part, children }) => {
188
189
  switch (part.type) {
@@ -205,6 +206,52 @@ Separate different types of content for distinct visual treatment:
205
206
  </MessagePrimitive.GroupedParts>
206
207
  ```
207
208
 
209
+ ### Keep Standalone Tool UIs Out of the Trace
210
+
211
+ Tool UIs fall into three buckets: prompting the user (human-in-the-loop), informing the user (generative UI), and traces of what the model is doing (routine tool calls). The first two should be surfaced on their own, while the last belongs folded into a collapsible chain-of-thought group.
212
+
213
+ Mark a tool with `display: "standalone"` to keep its UI out of the grouped trace. `human` tools and MCP apps are standalone automatically; every other tool defaults to `"inline"` and opts in explicitly:
214
+
215
+ ```tsx
216
+ const toolkit = defineToolkit({
217
+ ask_user: { type: "human", render: AskUI }, // standalone (forced)
218
+ search_web: { type: "frontend", render: SearchUI }, // inline trace (default)
219
+ checkout: {
220
+ type: "frontend",
221
+ render: CheckoutUI,
222
+ display: "standalone", // opt in
223
+ },
224
+ });
225
+ ```
226
+
227
+ The synthetic `"standalone-tool-call"` key on `groupPartByType` matches all of these. `MessagePrimitive.GroupedParts` passes the live tool-UI registry to `groupBy` as a second `context` argument, and the helper reads it to resolve the registry-driven cases — MCP-app calls are detected from the part alone, so nothing is threaded in:
228
+
229
+ ```tsx
230
+ <MessagePrimitive.GroupedParts
231
+ groupBy={groupPartByType({
232
+ reasoning: ["group-chainOfThought", "group-reasoning"],
233
+ "tool-call": ["group-chainOfThought", "group-tool"],
234
+ "standalone-tool-call": [], // ungrouped — rendered on its own
235
+ })}
236
+ >
237
+ {({ part, children }) => {
238
+ switch (part.type) {
239
+ case "group-chainOfThought":
240
+ return <div className="chain-of-thought">{children}</div>;
241
+ case "tool-call":
242
+ return part.toolUI ?? <ToolFallback {...part} />;
243
+ // ...
244
+ default:
245
+ return null;
246
+ }
247
+ }}
248
+ </MessagePrimitive.GroupedParts>;
249
+ ```
250
+
251
+ <Callout type="info">
252
+ The `"mcp-app"` key is deprecated in favor of `"standalone-tool-call"`, which is a superset (it also matches MCP-app tool calls). Existing `"mcp-app"` usage keeps working.
253
+ </Callout>
254
+
208
255
  ### Group by Custom Metadata
209
256
 
210
257
  Use any custom metadata in your parts for grouping:
@@ -219,7 +266,7 @@ const priorityStyles = {
219
266
  <MessagePrimitive.GroupedParts
220
267
  groupBy={(part) => {
221
268
  const priority = part.metadata?.priority;
222
- if (!priority) return null;
269
+ if (!priority) return [];
223
270
  return [`group-priority-${priority}`];
224
271
  }}
225
272
  >
@@ -300,9 +347,9 @@ const stream = createAssistantStream(async (controller) => {
300
347
  parameters={[
301
348
  {
302
349
  name: "groupBy",
303
- type: "(part: PartState, index: number, parts: readonly PartState[]) => GroupKey",
350
+ type: "(part: PartState) => readonly `group-${string}`[]",
304
351
  description:
305
- "Maps a part to a group-key path. Return null, undefined, or [] to leave the part ungrouped. Group keys must start with group-.",
352
+ "Maps a part to a group-key path. Return `[]` to leave the part ungrouped. Group keys must start with `group-`. Prefer `groupPartByType` for the common `part.type → path` case.",
306
353
  required: true,
307
354
  },
308
355
  {
@@ -315,6 +362,19 @@ const stream = createAssistantStream(async (controller) => {
315
362
  ]}
316
363
  />
317
364
 
365
+ ### groupPartByType helper
366
+
367
+ `groupPartByType` builds a `groupBy` from a `part.type → group-key path` map. Part types missing from the map are left ungrouped. The returned function carries an internal memo fingerprint so the tree survives unrelated re-renders.
368
+
369
+ ```typescript
370
+ import { groupPartByType } from "@assistant-ui/react";
371
+
372
+ groupPartByType({
373
+ reasoning: ["group-thought", "group-reasoning"],
374
+ "tool-call": ["group-thought", "group-tool"],
375
+ });
376
+ ```
377
+
318
378
  ### GroupPart Type
319
379
 
320
380
  ```typescript
@@ -331,34 +391,9 @@ type GroupPart<TKey extends `group-${string}` = `group-${string}`> = {
331
391
  2. **Handle ungrouped parts**: Always include leaf cases for the part types your message can render.
332
392
  3. **Only render `children` for groups**: Leaf parts receive a sentinel `children` value that throws if rendered accidentally.
333
393
  4. **Use `group-` prefixes**: Synthetic group keys must start with `group-` so they cannot collide with real part types.
334
- 5. **Keep `groupBy` stable**: Prefer a module-level function or `useCallback` for frequently re-rendering message trees.
335
394
 
336
395
  ## Common Patterns
337
396
 
338
- ### Conditional Grouping
339
-
340
- Only group when certain conditions are met:
341
-
342
- ```tsx
343
- <MessagePrimitive.GroupedParts
344
- groupBy={(part, index, parts) => {
345
- const hasManyParts = parts.length >= 5;
346
- if (!hasManyParts) return null;
347
- if (part.type === "tool-call") return ["group-tools"];
348
- return null;
349
- }}
350
- >
351
- {({ part, children }) => {
352
- if (part.type === "group-tools") {
353
- return <div className="rounded-lg border p-3">{children}</div>;
354
- }
355
- if (part.type === "tool-call") return part.toolUI ?? <ToolFallback {...part} />;
356
- if (part.type === "text") return <MarkdownText />;
357
- return null;
358
- }}
359
- </MessagePrimitive.GroupedParts>
360
- ```
361
-
362
397
  ### Nested Grouping
363
398
 
364
399
  Create hierarchical adjacent groups by returning multiple keys:
@@ -370,7 +405,7 @@ Create hierarchical adjacent groups by returning multiple keys:
370
405
  return ["group-chainOfThought", "group-reasoning"];
371
406
  if (part.type === "tool-call")
372
407
  return ["group-chainOfThought", `group-tool-${part.toolName}`];
373
- return null;
408
+ return [];
374
409
  }}
375
410
  >
376
411
  {({ part, children }) => {
@@ -391,10 +426,9 @@ Adjust group appearance based on the group node's status or indices:
391
426
 
392
427
  ```tsx
393
428
  <MessagePrimitive.GroupedParts
394
- groupBy={(part) => {
395
- if (part.type === "tool-call") return ["group-tools"];
396
- return null;
397
- }}
429
+ groupBy={groupPartByType({
430
+ "tool-call": ["group-tools"],
431
+ })}
398
432
  >
399
433
  {({ part, children }) => {
400
434
  if (part.type === "group-tools") {
@@ -31,7 +31,7 @@ Render reasoning parts through `MessagePrimitive.GroupedParts`. Group consecutiv
31
31
  While reasoning is streaming, `part.status.type === "running"`. Pass that to `defaultOpen` so the accordion auto-opens during streaming and lets the user collapse it once the model moves on.
32
32
 
33
33
  ```tsx title="/app/components/assistant-ui/thread.tsx"
34
- import { MessagePrimitive } from "@assistant-ui/react";
34
+ import { MessagePrimitive, groupPartByType } from "@assistant-ui/react";
35
35
  import { MarkdownText } from "@/components/assistant-ui/markdown-text";
36
36
  import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
37
37
  import {
@@ -47,10 +47,9 @@ const AssistantMessage: FC = () => {
47
47
  <MessagePrimitive.Root className="...">
48
48
  <div className="...">
49
49
  <MessagePrimitive.GroupedParts // [!code ++]
50
- groupBy={(part) => { // [!code ++]
51
- if (part.type === "reasoning") return ["group-reasoning"]; // [!code ++]
52
- return null; // [!code ++]
53
- }} // [!code ++]
50
+ groupBy={groupPartByType({ // [!code ++]
51
+ reasoning: ["group-reasoning"], // [!code ++]
52
+ })} // [!code ++]
54
53
  > // [!code ++]
55
54
  {({ part, children }) => { // [!code ++]
56
55
  switch (part.type) { // [!code ++]
@@ -9,6 +9,7 @@ import {
9
9
  ToolFallbackRunningSample,
10
10
  ToolFallbackCancelledSample,
11
11
  ToolFallbackStreamingSample,
12
+ ToolFallbackRequiresActionSample,
12
13
  } from "@/components/docs/samples/tool-fallback";
13
14
 
14
15
  <ToolFallbackSample />
@@ -71,6 +72,12 @@ Shows a muted appearance when a tool call was cancelled.
71
72
 
72
73
  <ToolFallbackCancelledSample />
73
74
 
75
+ ### Approval State
76
+
77
+ Shows the default Allow / Deny buttons rendered when a tool call enters `requires-action`. 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.
78
+
79
+ <ToolFallbackRequiresActionSample />
80
+
74
81
  ## Composable API
75
82
 
76
83
  All sub-components are exported for custom layouts:
@@ -83,6 +90,7 @@ All sub-components are exported for custom layouts:
83
90
  | `ToolFallback.Args` | Displays tool arguments |
84
91
  | `ToolFallback.Result` | Displays tool execution result |
85
92
  | `ToolFallback.Error` | Displays error or cancellation messages |
93
+ | `ToolFallback.Approval` | Renders Allow / Deny buttons for `requires-action` tools; wires `resume` / `addResult` / `respondToApproval` |
86
94
 
87
95
  ```tsx
88
96
  import {
@@ -93,6 +101,7 @@ import {
93
101
  ToolFallbackArgs,
94
102
  ToolFallbackResult,
95
103
  ToolFallbackError,
104
+ ToolFallbackApproval,
96
105
  } from "@/components/assistant-ui/tool-fallback";
97
106
 
98
107
  // Compound component syntax
@@ -101,6 +110,13 @@ import {
101
110
  <ToolFallback.Content>
102
111
  <ToolFallback.Error status={status} />
103
112
  <ToolFallback.Args argsText={argsText} />
113
+ <ToolFallback.Approval
114
+ addResult={addResult}
115
+ resume={resume}
116
+ interrupt={interrupt}
117
+ approval={approval}
118
+ respondToApproval={respondToApproval}
119
+ />
104
120
  <ToolFallback.Result result={result} />
105
121
  </ToolFallback.Content>
106
122
  </ToolFallback.Root>
@@ -29,10 +29,10 @@ This adds `/components/assistant-ui/tool-group.tsx` and `/components/assistant-u
29
29
 
30
30
  ### Use it in your application
31
31
 
32
- Use `MessagePrimitive.GroupedParts` and return `"group-tool"` for tool-call parts. The group case wraps `children`; the tool-call leaf renders the resolved tool UI or your fallback.
32
+ Use `MessagePrimitive.GroupedParts` with `groupPartByType` to map tool-call parts to `"group-tool"`. The group case wraps `children`; the tool-call leaf renders the resolved tool UI or your fallback.
33
33
 
34
34
  ```tsx title="/components/assistant-ui/thread.tsx"
35
- import { MessagePrimitive } from "@assistant-ui/react";
35
+ import { MessagePrimitive, groupPartByType } from "@assistant-ui/react";
36
36
  import { ToolFallback } from "@/components/assistant-ui/tool-fallback";
37
37
  import {
38
38
  ToolGroupContent,
@@ -44,10 +44,9 @@ const AssistantMessage = () => {
44
44
  return (
45
45
  <MessagePrimitive.Root>
46
46
  <MessagePrimitive.GroupedParts
47
- groupBy={(part) => {
48
- if (part.type === "tool-call") return ["group-tool"];
49
- return null;
50
- }}
47
+ groupBy={groupPartByType({
48
+ "tool-call": ["group-tool"],
49
+ })}
51
50
  >
52
51
  {({ part, children }) => {
53
52
  switch (part.type) {
@@ -4,7 +4,7 @@ description: Headless, composable activity heatmap components for React.
4
4
  platforms: ["react"]
5
5
  ---
6
6
 
7
- import { HeatGraphDemo } from "@/app/heat-graph/heat-graph-demo";
7
+ import { HeatGraphDemo } from "@/app/(demos)/heat-graph/heat-graph-demo";
8
8
 
9
9
  `heat-graph` provides headless, Radix-style primitives for building GitHub-style activity heatmap graphs.
10
10
 
@@ -13,7 +13,7 @@ platforms: ["react"]
13
13
  - **Headless** — Zero styling opinions, bring your own CSS / Tailwind.
14
14
  - **Composable** — Radix-style primitive parts you fully control.
15
15
  - **Tree-aware** — Automatic depth, parent / child collapse, time range computation.
16
- - **Tap-powered** — Built on the same `@assistant-ui/tap` reactive primitives as the runtimes.
16
+ - **Reactive** — Built on the same reactive core as the runtimes, so spans stream into your UI as they change.
17
17
 
18
18
  ## Installation
19
19
 
@@ -98,7 +98,7 @@ function SpanRow() {
98
98
 
99
99
  ### SpanResource
100
100
 
101
- Tap resource that ingests raw span data and exposes a tree-aware reactive state to primitives.
101
+ Resource that ingests raw span data and exposes a tree-aware reactive state to primitives.
102
102
 
103
103
  ```ts
104
104
  SpanResource({ spans }: { spans: SpanData[] }): ClientOutput<"span">;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","names":[],"sources":["../src/constants.ts"],"sourcesContent":["import { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport const ROOT_DIR = join(__dirname, \"../../../\");\nexport const PACKAGE_DIR = join(__dirname, \"../\");\n\nexport const EXAMPLES_PATH = join(ROOT_DIR, \"examples\");\n\nconst DOCS_BASE = join(PACKAGE_DIR, \".docs\");\nexport const DOCS_PATH = join(DOCS_BASE, \"raw/docs\");\nexport const CODE_EXAMPLES_PATH = join(DOCS_BASE, \"organized/code-examples\");\n\nexport const MDX_EXTENSION = \".mdx\";\nexport const MD_EXTENSION = \".md\";\n\nexport const MAX_FILE_SIZE = 10 * 1024 * 1024;\n\nexport const IS_PREPARE_MODE = process.argv[1]?.includes(\n \"prepare-docs/prepare\",\n);\n"],"mappings":";;;AAGA,MAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,GAAG,CAAC;AAExD,MAAa,WAAW,KAAK,WAAW,WAAW;AACnD,MAAa,cAAc,KAAK,WAAW,KAAK;AAEhD,MAAa,gBAAgB,KAAK,UAAU,UAAU;AAEtD,MAAM,YAAY,KAAK,aAAa,OAAO;AAC3C,MAAa,YAAY,KAAK,WAAW,UAAU;AACnD,MAAa,qBAAqB,KAAK,WAAW,yBAAyB;AAE3E,MAAa,gBAAgB;AAC7B,MAAa,eAAe;AAE5B,MAAa,gBAAgB,KAAK,OAAO;AAEzC,MAAa,kBAAkB,QAAQ,KAAK,IAAI,SAC9C,sBACF"}
1
+ {"version":3,"file":"constants.js","names":[],"sources":["../src/constants.ts"],"sourcesContent":["import { fileURLToPath } from \"node:url\";\nimport { dirname, join } from \"node:path\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nexport const ROOT_DIR = join(__dirname, \"../../../\");\nexport const PACKAGE_DIR = join(__dirname, \"../\");\n\nexport const EXAMPLES_PATH = join(ROOT_DIR, \"examples\");\n\nconst DOCS_BASE = join(PACKAGE_DIR, \".docs\");\nexport const DOCS_PATH = join(DOCS_BASE, \"raw/docs\");\nexport const CODE_EXAMPLES_PATH = join(DOCS_BASE, \"organized/code-examples\");\n\nexport const MDX_EXTENSION = \".mdx\";\nexport const MD_EXTENSION = \".md\";\n\nexport const MAX_FILE_SIZE = 10 * 1024 * 1024;\n\nexport const IS_PREPARE_MODE = process.argv[1]?.includes(\n \"prepare-docs/prepare\",\n);\n"],"mappings":";;;AAGA,MAAM,YAAY,QAAQ,cAAc,OAAO,KAAK,GAAG,CAAC;AAExD,MAAa,WAAW,KAAK,WAAW,WAAW;AACnD,MAAa,cAAc,KAAK,WAAW,KAAK;AAEhD,MAAa,gBAAgB,KAAK,UAAU,UAAU;AAEtD,MAAM,YAAY,KAAK,aAAa,OAAO;AAC3C,MAAa,YAAY,KAAK,WAAW,UAAU;AACnD,MAAa,qBAAqB,KAAK,WAAW,yBAAyB;AAE3E,MAAa,gBAAgB;AAC7B,MAAa,eAAe;AAE5B,MAAa,gBAAgB,KAAK,OAAO;AAEzC,MAAa,kBAAkB,QAAQ,KAAK,EAAE,EAAE,SAC9C,sBACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;cAca,MAAA,EAAM,SAGjB;AAAA,iBAeoB,SAAA,CAAA,GAAS,OAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;cAca,MAAA,EAAM,SAGjB;AAAA,iBAeoB,SAAA,IAAS,OAAA"}
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { docsTools } from \"./tools/docs.js\";\nimport { examplesTools } from \"./tools/examples.js\";\nimport { logger } from \"./utils/logger.js\";\nimport { PACKAGE_DIR } from \"./constants.js\";\n\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst packageJson = JSON.parse(\n readFileSync(join(PACKAGE_DIR, \"package.json\"), \"utf-8\"),\n);\n\nexport const server = new McpServer({\n name: \"assistant-ui-docs\",\n version: packageJson.version,\n});\n\nserver.tool(\n docsTools.name,\n docsTools.description,\n docsTools.parameters,\n docsTools.execute,\n);\nserver.tool(\n examplesTools.name,\n examplesTools.description,\n examplesTools.parameters,\n examplesTools.execute,\n);\n\nexport async function runServer() {\n try {\n logger.info(\n `Starting assistant-ui MCP docs server v${packageJson.version}`,\n );\n const transport = new StdioServerTransport();\n await server.connect(transport);\n } catch (error) {\n logger.error(\"Failed to start MCP server\", error);\n process.exit(1);\n }\n}\n\nif (import.meta.url === `file://${process.argv[1]}`) {\n void runServer().catch((error) => {\n console.error(\"Failed to start server:\", error);\n process.exit(1);\n });\n}\n"],"mappings":";;;;;;;;;AAUA,MAAM,cAAc,KAAK,MACvB,aAAa,KAAK,aAAa,cAAc,GAAG,OAAO,CACzD;AAEA,MAAa,SAAS,IAAI,UAAU;CAClC,MAAM;CACN,SAAS,YAAY;AACvB,CAAC;AAED,OAAO,KACL,UAAU,MACV,UAAU,aACV,UAAU,YACV,UAAU,OACZ;AACA,OAAO,KACL,cAAc,MACd,cAAc,aACd,cAAc,YACd,cAAc,OAChB;AAEA,eAAsB,YAAY;CAChC,IAAI;EACF,OAAO,KACL,0CAA0C,YAAY,SACxD;EACA,MAAM,YAAY,IAAI,qBAAqB;EAC3C,MAAM,OAAO,QAAQ,SAAS;CAChC,SAAS,OAAO;EACd,OAAO,MAAM,8BAA8B,KAAK;EAChD,QAAQ,KAAK,CAAC;CAChB;AACF;AAEA,IAAI,OAAO,KAAK,QAAQ,UAAU,QAAQ,KAAK,MAC7C,UAAe,EAAE,OAAO,UAAU;CAChC,QAAQ,MAAM,2BAA2B,KAAK;CAC9C,QAAQ,KAAK,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport { docsTools } from \"./tools/docs.js\";\nimport { examplesTools } from \"./tools/examples.js\";\nimport { logger } from \"./utils/logger.js\";\nimport { PACKAGE_DIR } from \"./constants.js\";\n\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst packageJson = JSON.parse(\n readFileSync(join(PACKAGE_DIR, \"package.json\"), \"utf-8\"),\n);\n\nexport const server = new McpServer({\n name: \"assistant-ui-docs\",\n version: packageJson.version,\n});\n\nserver.tool(\n docsTools.name,\n docsTools.description,\n docsTools.parameters,\n docsTools.execute,\n);\nserver.tool(\n examplesTools.name,\n examplesTools.description,\n examplesTools.parameters,\n examplesTools.execute,\n);\n\nexport async function runServer() {\n try {\n logger.info(\n `Starting assistant-ui MCP docs server v${packageJson.version}`,\n );\n const transport = new StdioServerTransport();\n await server.connect(transport);\n } catch (error) {\n logger.error(\"Failed to start MCP server\", error);\n process.exit(1);\n }\n}\n\nif (import.meta.url === `file://${process.argv[1]}`) {\n void runServer().catch((error) => {\n console.error(\"Failed to start server:\", error);\n process.exit(1);\n });\n}\n"],"mappings":";;;;;;;;;AAUA,MAAM,cAAc,KAAK,MACvB,aAAa,KAAK,aAAa,cAAc,GAAG,OAAO,CACzD;AAEA,MAAa,SAAS,IAAI,UAAU;CAClC,MAAM;CACN,SAAS,YAAY;AACvB,CAAC;AAED,OAAO,KACL,UAAU,MACV,UAAU,aACV,UAAU,YACV,UAAU,OACZ;AACA,OAAO,KACL,cAAc,MACd,cAAc,aACd,cAAc,YACd,cAAc,OAChB;AAEA,eAAsB,YAAY;CAChC,IAAI;EACF,OAAO,KACL,0CAA0C,YAAY,SACxD;EACA,MAAM,YAAY,IAAI,qBAAqB;EAC3C,MAAM,OAAO,QAAQ,SAAS;CAChC,SAAS,OAAO;EACd,OAAO,MAAM,8BAA8B,KAAK;EAChD,QAAQ,KAAK,CAAC;CAChB;AACF;AAEA,IAAI,OAAO,KAAK,QAAQ,UAAU,QAAQ,KAAK,MAC7C,UAAe,CAAC,CAAC,OAAO,UAAU;CAChC,QAAQ,MAAM,2BAA2B,KAAK;CAC9C,QAAQ,KAAK,CAAC;AAChB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"code-examples.d.ts","names":[],"sources":["../../src/prepare-docs/code-examples.ts"],"mappings":";iBA2FsB,mBAAA,CAAA,GAAuB,OAAO"}
1
+ {"version":3,"file":"code-examples.d.ts","names":[],"sources":["../../src/prepare-docs/code-examples.ts"],"mappings":";iBA2FsB,mBAAA,IAAuB,OAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"code-examples.js","names":[],"sources":["../../src/prepare-docs/code-examples.ts"],"sourcesContent":["import { rm, mkdir, readdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join, relative, extname } from \"node:path\";\nimport { logger } from \"../utils/logger.js\";\nimport { ROOT_DIR, EXAMPLES_PATH } from \"../constants.js\";\n\nconst OUTPUT_DIR = join(\n ROOT_DIR,\n \"packages/mcp-docs-server/.docs/organized/code-examples\",\n);\nconst MAX_LINES = 10000;\n\ninterface FileContent {\n path: string;\n content: string;\n}\n\nasync function scanDirectory(\n dir: string,\n baseDir: string,\n): Promise<FileContent[]> {\n const files: FileContent[] = [];\n\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n const skipDirs = [\n \"node_modules\",\n \"dist\",\n \"build\",\n \".next\",\n \".git\",\n \".turbo\",\n ];\n if (!skipDirs.includes(entry.name)) {\n const subFiles = await scanDirectory(fullPath, baseDir);\n files.push(...subFiles);\n }\n } else if (entry.isFile()) {\n const includeExts = [\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".json\",\n \".css\",\n \".md\",\n \".mdx\",\n ];\n const ext = extname(entry.name).toLowerCase();\n\n if (\n includeExts.includes(ext) ||\n entry.name === \"package.json\" ||\n entry.name === \"tsconfig.json\"\n ) {\n try {\n const content = await readFile(fullPath, \"utf-8\");\n const relativePath = relative(baseDir, fullPath);\n files.push({ path: relativePath, content });\n } catch (error) {\n logger.warn(`Failed to read file: ${fullPath}`, error);\n }\n }\n }\n }\n } catch (error) {\n logger.error(`Failed to scan directory: ${dir}`, error);\n }\n\n return files;\n}\n\nfunction getFileType(filename: string): string {\n const ext = extname(filename).toLowerCase();\n const extMap: Record<string, string> = {\n \".ts\": \"typescript\",\n \".tsx\": \"tsx\",\n \".js\": \"javascript\",\n \".jsx\": \"jsx\",\n \".json\": \"json\",\n \".css\": \"css\",\n \".md\": \"markdown\",\n \".mdx\": \"mdx\",\n };\n return extMap[ext] || \"text\";\n}\n\nexport async function prepareCodeExamples(): Promise<void> {\n logger.info(\"Preparing code examples...\");\n\n try {\n await rm(OUTPUT_DIR, { recursive: true, force: true });\n await mkdir(OUTPUT_DIR, { recursive: true });\n\n const exampleDirs = await readdir(EXAMPLES_PATH, { withFileTypes: true });\n\n for (const dir of exampleDirs) {\n if (dir.isDirectory() && !dir.name.startsWith(\".\")) {\n const examplePath = join(EXAMPLES_PATH, dir.name);\n logger.info(`Processing example: ${dir.name}`);\n\n let description = \"\";\n try {\n const packageJsonPath = join(examplePath, \"package.json\");\n const packageJson = JSON.parse(\n await readFile(packageJsonPath, \"utf-8\"),\n );\n description = packageJson.description || \"\";\n } catch (error: any) {\n if (error?.code !== \"ENOENT\") {\n logger.warn(`Failed to read package.json for ${dir.name}:`, error);\n } else {\n logger.debug(`No package.json found for example: ${dir.name}`);\n }\n }\n\n const files = await scanDirectory(examplePath, examplePath);\n\n files.sort((a, b) => a.path.localeCompare(b.path));\n\n let markdown = `# Example: ${dir.name}\\n\\n`;\n if (description) {\n markdown += `${description}\\n\\n`;\n }\n\n let totalLines = 0;\n for (const file of files) {\n const lines = file.content.split(\"\\n\").length;\n if (totalLines + lines > MAX_LINES) {\n markdown += `\\n_Note: Additional files truncated due to size limits_\\n`;\n break;\n }\n\n // Normalize Windows backslashes to forward slashes for consistent markdown output\n markdown += `## ${file.path.replace(/\\\\/g, \"/\")}\\n\\n`;\n markdown += `\\`\\`\\`${getFileType(file.path)}\\n`;\n markdown += file.content;\n markdown += `\\n\\`\\`\\`\\n\\n`;\n\n totalLines += lines;\n }\n\n const outputPath = join(OUTPUT_DIR, `${dir.name}.md`);\n await writeFile(outputPath, markdown, \"utf-8\");\n logger.debug(`Created example: ${outputPath}`);\n }\n }\n\n logger.info(\"Code examples preparation complete\");\n } catch (error) {\n logger.error(\"Failed to prepare code examples\", error);\n throw error;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"code-examples.js","names":[],"sources":["../../src/prepare-docs/code-examples.ts"],"sourcesContent":["import { rm, mkdir, readdir, readFile, writeFile } from \"node:fs/promises\";\nimport { join, relative, extname } from \"node:path\";\nimport { logger } from \"../utils/logger.js\";\nimport { ROOT_DIR, EXAMPLES_PATH } from \"../constants.js\";\n\nconst OUTPUT_DIR = join(\n ROOT_DIR,\n \"packages/mcp-docs-server/.docs/organized/code-examples\",\n);\nconst MAX_LINES = 10000;\n\ninterface FileContent {\n path: string;\n content: string;\n}\n\nasync function scanDirectory(\n dir: string,\n baseDir: string,\n): Promise<FileContent[]> {\n const files: FileContent[] = [];\n\n try {\n const entries = await readdir(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(dir, entry.name);\n\n if (entry.isDirectory()) {\n const skipDirs = [\n \"node_modules\",\n \"dist\",\n \"build\",\n \".next\",\n \".git\",\n \".turbo\",\n ];\n if (!skipDirs.includes(entry.name)) {\n const subFiles = await scanDirectory(fullPath, baseDir);\n files.push(...subFiles);\n }\n } else if (entry.isFile()) {\n const includeExts = [\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".json\",\n \".css\",\n \".md\",\n \".mdx\",\n ];\n const ext = extname(entry.name).toLowerCase();\n\n if (\n includeExts.includes(ext) ||\n entry.name === \"package.json\" ||\n entry.name === \"tsconfig.json\"\n ) {\n try {\n const content = await readFile(fullPath, \"utf-8\");\n const relativePath = relative(baseDir, fullPath);\n files.push({ path: relativePath, content });\n } catch (error) {\n logger.warn(`Failed to read file: ${fullPath}`, error);\n }\n }\n }\n }\n } catch (error) {\n logger.error(`Failed to scan directory: ${dir}`, error);\n }\n\n return files;\n}\n\nfunction getFileType(filename: string): string {\n const ext = extname(filename).toLowerCase();\n const extMap: Record<string, string> = {\n \".ts\": \"typescript\",\n \".tsx\": \"tsx\",\n \".js\": \"javascript\",\n \".jsx\": \"jsx\",\n \".json\": \"json\",\n \".css\": \"css\",\n \".md\": \"markdown\",\n \".mdx\": \"mdx\",\n };\n return extMap[ext] || \"text\";\n}\n\nexport async function prepareCodeExamples(): Promise<void> {\n logger.info(\"Preparing code examples...\");\n\n try {\n await rm(OUTPUT_DIR, { recursive: true, force: true });\n await mkdir(OUTPUT_DIR, { recursive: true });\n\n const exampleDirs = await readdir(EXAMPLES_PATH, { withFileTypes: true });\n\n for (const dir of exampleDirs) {\n if (dir.isDirectory() && !dir.name.startsWith(\".\")) {\n const examplePath = join(EXAMPLES_PATH, dir.name);\n logger.info(`Processing example: ${dir.name}`);\n\n let description = \"\";\n try {\n const packageJsonPath = join(examplePath, \"package.json\");\n const packageJson = JSON.parse(\n await readFile(packageJsonPath, \"utf-8\"),\n );\n description = packageJson.description || \"\";\n } catch (error: any) {\n if (error?.code !== \"ENOENT\") {\n logger.warn(`Failed to read package.json for ${dir.name}:`, error);\n } else {\n logger.debug(`No package.json found for example: ${dir.name}`);\n }\n }\n\n const files = await scanDirectory(examplePath, examplePath);\n\n files.sort((a, b) => a.path.localeCompare(b.path));\n\n let markdown = `# Example: ${dir.name}\\n\\n`;\n if (description) {\n markdown += `${description}\\n\\n`;\n }\n\n let totalLines = 0;\n for (const file of files) {\n const lines = file.content.split(\"\\n\").length;\n if (totalLines + lines > MAX_LINES) {\n markdown += `\\n_Note: Additional files truncated due to size limits_\\n`;\n break;\n }\n\n // Normalize Windows backslashes to forward slashes for consistent markdown output\n markdown += `## ${file.path.replace(/\\\\/g, \"/\")}\\n\\n`;\n markdown += `\\`\\`\\`${getFileType(file.path)}\\n`;\n markdown += file.content;\n markdown += `\\n\\`\\`\\`\\n\\n`;\n\n totalLines += lines;\n }\n\n const outputPath = join(OUTPUT_DIR, `${dir.name}.md`);\n await writeFile(outputPath, markdown, \"utf-8\");\n logger.debug(`Created example: ${outputPath}`);\n }\n }\n\n logger.info(\"Code examples preparation complete\");\n } catch (error) {\n logger.error(\"Failed to prepare code examples\", error);\n throw error;\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"copy-raw.d.ts","names":[],"sources":["../../src/prepare-docs/copy-raw.ts"],"mappings":";iBAkCsB,OAAA,CAAA,GAAW,OAAO"}
1
+ {"version":3,"file":"copy-raw.d.ts","names":[],"sources":["../../src/prepare-docs/copy-raw.ts"],"mappings":";iBAkCsB,OAAA,IAAW,OAAO"}
@@ -1 +1 @@
1
- {"version":3,"file":"copy-raw.js","names":[],"sources":["../../src/prepare-docs/copy-raw.ts"],"sourcesContent":["import { rm, mkdir, readdir, copyFile } from \"node:fs/promises\";\nimport { join, extname } from \"node:path\";\nimport { logger } from \"../utils/logger.js\";\nimport { ROOT_DIR } from \"../constants.js\";\n\nconst DOCS_SOURCE = join(ROOT_DIR, \"apps/docs/content/docs\");\nconst BLOG_SOURCE = join(ROOT_DIR, \"apps/docs/content/blog\");\nconst DOCS_DEST = join(ROOT_DIR, \"packages/mcp-docs-server/.docs/raw\");\n\nasync function copyDir(src: string, dest: string): Promise<void> {\n try {\n await mkdir(dest, { recursive: true });\n const entries = await readdir(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = join(src, entry.name);\n const destPath = join(dest, entry.name);\n\n if (entry.isDirectory()) {\n await copyDir(srcPath, destPath);\n } else if (entry.isFile()) {\n const ext = extname(entry.name).toLowerCase();\n if (ext === \".mdx\" || ext === \".md\") {\n await copyFile(srcPath, destPath);\n logger.debug(`Copied: ${srcPath} -> ${destPath}`);\n }\n }\n }\n } catch (error) {\n logger.error(`Failed to copy directory: ${src}`, error);\n throw error;\n }\n}\n\nexport async function copyRaw(): Promise<void> {\n logger.info(\"Copying raw documentation files...\");\n\n try {\n await rm(DOCS_DEST, { recursive: true, force: true });\n await mkdir(DOCS_DEST, { recursive: true });\n\n const docsPath = join(DOCS_DEST, \"docs\");\n await copyDir(DOCS_SOURCE, docsPath);\n logger.info(`Copied documentation to ${docsPath}`);\n\n const blogPath = join(DOCS_DEST, \"blog\");\n await copyDir(BLOG_SOURCE, blogPath);\n logger.info(`Copied blog posts to ${blogPath}`);\n\n logger.info(\"Raw documentation copy complete\");\n } catch (error) {\n logger.error(\"Failed to copy raw documentation\", error);\n throw error;\n }\n}\n"],"mappings":";;;;;AAKA,MAAM,cAAc,KAAK,UAAU,wBAAwB;AAC3D,MAAM,cAAc,KAAK,UAAU,wBAAwB;AAC3D,MAAM,YAAY,KAAK,UAAU,oCAAoC;AAErE,eAAe,QAAQ,KAAa,MAA6B;CAC/D,IAAI;EACF,MAAM,MAAM,MAAM,EAAE,WAAW,KAAK,CAAC;EACrC,MAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;EAE1D,KAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,UAAU,KAAK,KAAK,MAAM,IAAI;GACpC,MAAM,WAAW,KAAK,MAAM,MAAM,IAAI;GAEtC,IAAI,MAAM,YAAY,GACpB,MAAM,QAAQ,SAAS,QAAQ;QAC1B,IAAI,MAAM,OAAO,GAAG;IACzB,MAAM,MAAM,QAAQ,MAAM,IAAI,EAAE,YAAY;IAC5C,IAAI,QAAQ,UAAU,QAAQ,OAAO;KACnC,MAAM,SAAS,SAAS,QAAQ;KAChC,OAAO,MAAM,WAAW,QAAQ,MAAM,UAAU;IAClD;GACF;EACF;CACF,SAAS,OAAO;EACd,OAAO,MAAM,6BAA6B,OAAO,KAAK;EACtD,MAAM;CACR;AACF;AAEA,eAAsB,UAAyB;CAC7C,OAAO,KAAK,oCAAoC;CAEhD,IAAI;EACF,MAAM,GAAG,WAAW;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;EACpD,MAAM,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;EAE1C,MAAM,WAAW,KAAK,WAAW,MAAM;EACvC,MAAM,QAAQ,aAAa,QAAQ;EACnC,OAAO,KAAK,2BAA2B,UAAU;EAEjD,MAAM,WAAW,KAAK,WAAW,MAAM;EACvC,MAAM,QAAQ,aAAa,QAAQ;EACnC,OAAO,KAAK,wBAAwB,UAAU;EAE9C,OAAO,KAAK,iCAAiC;CAC/C,SAAS,OAAO;EACd,OAAO,MAAM,oCAAoC,KAAK;EACtD,MAAM;CACR;AACF"}
1
+ {"version":3,"file":"copy-raw.js","names":[],"sources":["../../src/prepare-docs/copy-raw.ts"],"sourcesContent":["import { rm, mkdir, readdir, copyFile } from \"node:fs/promises\";\nimport { join, extname } from \"node:path\";\nimport { logger } from \"../utils/logger.js\";\nimport { ROOT_DIR } from \"../constants.js\";\n\nconst DOCS_SOURCE = join(ROOT_DIR, \"apps/docs/content/docs\");\nconst BLOG_SOURCE = join(ROOT_DIR, \"apps/docs/content/blog\");\nconst DOCS_DEST = join(ROOT_DIR, \"packages/mcp-docs-server/.docs/raw\");\n\nasync function copyDir(src: string, dest: string): Promise<void> {\n try {\n await mkdir(dest, { recursive: true });\n const entries = await readdir(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = join(src, entry.name);\n const destPath = join(dest, entry.name);\n\n if (entry.isDirectory()) {\n await copyDir(srcPath, destPath);\n } else if (entry.isFile()) {\n const ext = extname(entry.name).toLowerCase();\n if (ext === \".mdx\" || ext === \".md\") {\n await copyFile(srcPath, destPath);\n logger.debug(`Copied: ${srcPath} -> ${destPath}`);\n }\n }\n }\n } catch (error) {\n logger.error(`Failed to copy directory: ${src}`, error);\n throw error;\n }\n}\n\nexport async function copyRaw(): Promise<void> {\n logger.info(\"Copying raw documentation files...\");\n\n try {\n await rm(DOCS_DEST, { recursive: true, force: true });\n await mkdir(DOCS_DEST, { recursive: true });\n\n const docsPath = join(DOCS_DEST, \"docs\");\n await copyDir(DOCS_SOURCE, docsPath);\n logger.info(`Copied documentation to ${docsPath}`);\n\n const blogPath = join(DOCS_DEST, \"blog\");\n await copyDir(BLOG_SOURCE, blogPath);\n logger.info(`Copied blog posts to ${blogPath}`);\n\n logger.info(\"Raw documentation copy complete\");\n } catch (error) {\n logger.error(\"Failed to copy raw documentation\", error);\n throw error;\n }\n}\n"],"mappings":";;;;;AAKA,MAAM,cAAc,KAAK,UAAU,wBAAwB;AAC3D,MAAM,cAAc,KAAK,UAAU,wBAAwB;AAC3D,MAAM,YAAY,KAAK,UAAU,oCAAoC;AAErE,eAAe,QAAQ,KAAa,MAA6B;CAC/D,IAAI;EACF,MAAM,MAAM,MAAM,EAAE,WAAW,KAAK,CAAC;EACrC,MAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;EAE1D,KAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,UAAU,KAAK,KAAK,MAAM,IAAI;GACpC,MAAM,WAAW,KAAK,MAAM,MAAM,IAAI;GAEtC,IAAI,MAAM,YAAY,GACpB,MAAM,QAAQ,SAAS,QAAQ;QAC1B,IAAI,MAAM,OAAO,GAAG;IACzB,MAAM,MAAM,QAAQ,MAAM,IAAI,CAAC,CAAC,YAAY;IAC5C,IAAI,QAAQ,UAAU,QAAQ,OAAO;KACnC,MAAM,SAAS,SAAS,QAAQ;KAChC,OAAO,MAAM,WAAW,QAAQ,MAAM,UAAU;IAClD;GACF;EACF;CACF,SAAS,OAAO;EACd,OAAO,MAAM,6BAA6B,OAAO,KAAK;EACtD,MAAM;CACR;AACF;AAEA,eAAsB,UAAyB;CAC7C,OAAO,KAAK,oCAAoC;CAEhD,IAAI;EACF,MAAM,GAAG,WAAW;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;EACpD,MAAM,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;EAE1C,MAAM,WAAW,KAAK,WAAW,MAAM;EACvC,MAAM,QAAQ,aAAa,QAAQ;EACnC,OAAO,KAAK,2BAA2B,UAAU;EAEjD,MAAM,WAAW,KAAK,WAAW,MAAM;EACvC,MAAM,QAAQ,aAAa,QAAQ;EACnC,OAAO,KAAK,wBAAwB,UAAU;EAE9C,OAAO,KAAK,iCAAiC;CAC/C,SAAS,OAAO;EACd,OAAO,MAAM,oCAAoC,KAAK;EACtD,MAAM;CACR;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"prepare.js","names":[],"sources":["../../src/prepare-docs/prepare.ts"],"sourcesContent":["import { logger } from \"../utils/logger.js\";\nimport { copyRaw } from \"./copy-raw.js\";\nimport { prepareCodeExamples } from \"./code-examples.js\";\n\nasync function prepare(): Promise<void> {\n logger.info(\"Starting documentation preparation...\");\n\n try {\n await copyRaw();\n await prepareCodeExamples();\n\n logger.info(\"Documentation preparation complete\");\n } catch (error) {\n logger.error(\"Documentation preparation failed\", error);\n throw error;\n }\n}\n\nif (import.meta.url === `file://${process.argv[1]}`) {\n prepare().catch((error) => {\n logger.error(\"Preparation failed\", error);\n process.exit(1);\n });\n}\n"],"mappings":";;;;AAIA,eAAe,UAAyB;CACtC,OAAO,KAAK,uCAAuC;CAEnD,IAAI;EACF,MAAM,QAAQ;EACd,MAAM,oBAAoB;EAE1B,OAAO,KAAK,oCAAoC;CAClD,SAAS,OAAO;EACd,OAAO,MAAM,oCAAoC,KAAK;EACtD,MAAM;CACR;AACF;AAEA,IAAI,OAAO,KAAK,QAAQ,UAAU,QAAQ,KAAK,MAC7C,QAAQ,EAAE,OAAO,UAAU;CACzB,OAAO,MAAM,sBAAsB,KAAK;CACxC,QAAQ,KAAK,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"prepare.js","names":[],"sources":["../../src/prepare-docs/prepare.ts"],"sourcesContent":["import { logger } from \"../utils/logger.js\";\nimport { copyRaw } from \"./copy-raw.js\";\nimport { prepareCodeExamples } from \"./code-examples.js\";\n\nasync function prepare(): Promise<void> {\n logger.info(\"Starting documentation preparation...\");\n\n try {\n await copyRaw();\n await prepareCodeExamples();\n\n logger.info(\"Documentation preparation complete\");\n } catch (error) {\n logger.error(\"Documentation preparation failed\", error);\n throw error;\n }\n}\n\nif (import.meta.url === `file://${process.argv[1]}`) {\n prepare().catch((error) => {\n logger.error(\"Preparation failed\", error);\n process.exit(1);\n });\n}\n"],"mappings":";;;;AAIA,eAAe,UAAyB;CACtC,OAAO,KAAK,uCAAuC;CAEnD,IAAI;EACF,MAAM,QAAQ;EACd,MAAM,oBAAoB;EAE1B,OAAO,KAAK,oCAAoC;CAClD,SAAS,OAAO;EACd,OAAO,MAAM,oCAAoC,KAAK;EACtD,MAAM;CACR;AACF;AAEA,IAAI,OAAO,KAAK,QAAQ,UAAU,QAAQ,KAAK,MAC7C,QAAQ,CAAC,CAAC,OAAO,UAAU;CACzB,OAAO,MAAM,sBAAsB,KAAK;CACxC,QAAQ,KAAK,CAAC;AAChB,CAAC"}