@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.
- package/.docs/organized/code-examples/waterfall.md +20 -22
- package/.docs/organized/code-examples/with-a2a.md +24 -24
- package/.docs/organized/code-examples/with-ag-ui.md +30 -25
- package/.docs/organized/code-examples/with-ai-sdk-v6.md +11 -9
- package/.docs/organized/code-examples/with-artifacts.md +49 -37
- package/.docs/organized/code-examples/with-assistant-transport.md +63 -51
- package/.docs/organized/code-examples/with-browser-extension.md +22 -10
- package/.docs/organized/code-examples/with-chain-of-thought.md +406 -87
- package/.docs/organized/code-examples/with-cloud-standalone.md +25 -24
- package/.docs/organized/code-examples/with-cloud.md +11 -9
- package/.docs/organized/code-examples/with-custom-thread-list.md +14 -12
- package/.docs/organized/code-examples/with-elevenlabs-conversational.md +23 -21
- package/.docs/organized/code-examples/with-elevenlabs-scribe.md +14 -13
- package/.docs/organized/code-examples/with-expo.md +44 -29
- package/.docs/organized/code-examples/with-external-store.md +9 -7
- package/.docs/organized/code-examples/with-ffmpeg.md +322 -285
- package/.docs/organized/code-examples/with-generative-ui.md +1066 -256
- package/.docs/organized/code-examples/with-google-adk.md +10 -8
- package/.docs/organized/code-examples/with-heat-graph.md +13 -11
- package/.docs/organized/code-examples/with-image-generation.md +19 -17
- package/.docs/organized/code-examples/with-interactables.md +317 -239
- package/.docs/organized/code-examples/with-langchain.md +14 -12
- package/.docs/organized/code-examples/with-langgraph.md +91 -83
- package/.docs/organized/code-examples/with-livekit.md +24 -22
- package/.docs/organized/code-examples/with-mcp.md +18 -12
- package/.docs/organized/code-examples/with-opencode.md +66 -66
- package/.docs/organized/code-examples/with-react-hook-form.md +19 -17
- package/.docs/organized/code-examples/with-react-ink.md +297 -102
- package/.docs/organized/code-examples/with-react-router.md +17 -15
- package/.docs/organized/code-examples/with-resumable-stream.md +15 -14
- package/.docs/organized/code-examples/with-store.md +78 -76
- package/.docs/organized/code-examples/with-tanstack.md +13 -14
- package/.docs/organized/code-examples/with-tap-runtime.md +26 -24
- package/.docs/raw/docs/(docs)/architecture.mdx +94 -42
- package/.docs/raw/docs/(docs)/cli.mdx +1 -2
- package/.docs/raw/docs/(docs)/installation.mdx +1 -1
- package/.docs/raw/docs/(reference)/api-reference/adapters/persistence.mdx +5 -1
- package/.docs/raw/docs/(reference)/api-reference/external-store/message-conversion.mdx +15 -15
- package/.docs/raw/docs/(reference)/api-reference/external-store/runtime.mdx +14 -1
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/index.mdx +18 -0
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/rendering.mdx +33 -0
- package/.docs/raw/docs/(reference)/api-reference/generative-ui/spec.mdx +45 -0
- package/.docs/raw/docs/(reference)/api-reference/hooks/composer-triggers.mdx +41 -41
- package/.docs/raw/docs/(reference)/api-reference/hooks/model-context.mdx +19 -1
- package/.docs/raw/docs/(reference)/api-reference/hooks/primitives.mdx +122 -122
- package/.docs/raw/docs/(reference)/api-reference/integrations/react-ai-sdk.mdx +43 -2
- package/.docs/raw/docs/(reference)/api-reference/model-context/context.mdx +6 -0
- package/.docs/raw/docs/(reference)/api-reference/overview.mdx +4 -6
- package/.docs/raw/docs/(reference)/api-reference/primitives/message.mdx +30 -0
- package/.docs/raw/docs/(reference)/api-reference/tools/component-tools.mdx +20 -3
- package/.docs/raw/docs/(reference)/api-reference/tools/index.mdx +8 -8
- package/.docs/raw/docs/(reference)/api-reference/tools/rendering.mdx +52 -4
- package/.docs/raw/docs/(reference)/api-reference/tools/toolkits.mdx +100 -10
- package/.docs/raw/docs/(reference)/api-reference/utilities/miscellaneous.mdx +7 -59
- package/.docs/raw/docs/cloud/ai-sdk.mdx +0 -2
- package/.docs/raw/docs/{(docs)/copilots → copilots}/model-context.mdx +34 -26
- package/.docs/raw/docs/{(docs)/copilots → copilots}/motivation.mdx +32 -26
- package/.docs/raw/docs/guides/chain-of-thought.mdx +7 -9
- package/.docs/raw/docs/guides/context-api.mdx +2 -1
- package/.docs/raw/docs/guides/index.mdx +3 -12
- package/.docs/raw/docs/guides/mentions.mdx +4 -4
- package/.docs/raw/docs/guides/slash-commands.mdx +1 -1
- package/.docs/raw/docs/guides/suggestions.mdx +1 -1
- package/.docs/raw/docs/ink/adapters.mdx +23 -1
- package/.docs/raw/docs/ink/hooks.mdx +101 -85
- package/.docs/raw/docs/ink/migration.mdx +1 -1
- package/.docs/raw/docs/ink/primitives.mdx +2 -2
- package/.docs/raw/docs/integrations/frameworks/ai-sdk.mdx +1 -1
- package/.docs/raw/docs/integrations/index.mdx +2 -2
- package/.docs/raw/docs/integrations/persistence/custom-adapter.mdx +17 -2
- package/.docs/raw/docs/migrations/toolkit-tools.mdx +232 -0
- package/.docs/raw/docs/primitives/chain-of-thought.mdx +10 -16
- package/.docs/raw/docs/primitives/message.mdx +9 -10
- package/.docs/raw/docs/react-native/hooks.mdx +62 -79
- package/.docs/raw/docs/react-native/migration.mdx +1 -1
- package/.docs/raw/docs/react-native/primitives.mdx +2 -2
- package/.docs/raw/docs/runtimes/a2a/client-and-hooks.mdx +3 -0
- package/.docs/raw/docs/runtimes/ag-ui/runtime-options.mdx +41 -0
- package/.docs/raw/docs/runtimes/ai-sdk/v6.mdx +122 -1
- package/.docs/raw/docs/runtimes/concepts/architecture.mdx +46 -4
- package/.docs/raw/docs/runtimes/concepts/threads.mdx +7 -1
- package/.docs/raw/docs/runtimes/custom/assistant-transport.mdx +54 -12
- package/.docs/raw/docs/runtimes/custom/external-store.mdx +62 -4
- package/.docs/raw/docs/runtimes/custom/local-runtime.mdx +30 -7
- package/.docs/raw/docs/runtimes/google-adk/hooks.mdx +108 -38
- package/.docs/raw/docs/runtimes/langgraph/generative-ui.mdx +2 -2
- package/.docs/raw/docs/runtimes/langgraph/streaming.mdx +14 -1
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-2.mdx +64 -50
- package/.docs/raw/docs/runtimes/langgraph/tutorial/part-3.mdx +98 -86
- package/.docs/raw/docs/tools/backend.mdx +144 -0
- package/.docs/raw/docs/tools/defining-tools.mdx +538 -0
- package/.docs/raw/docs/tools/dynamic-tools.mdx +110 -0
- package/.docs/raw/docs/tools/generative-ui.mdx +214 -0
- package/.docs/raw/docs/tools/index.mdx +71 -0
- package/.docs/raw/docs/{guides → tools}/interactables.mdx +1 -1
- package/.docs/raw/docs/{integrations/tools → tools}/mcp.mdx +145 -50
- package/.docs/raw/docs/{guides → tools}/multi-agent.mdx +15 -17
- package/.docs/raw/docs/tools/tool-ui.mdx +967 -0
- package/.docs/raw/docs/{integrations/tools/react-mcp.mdx → tools/user-managed-mcp.mdx} +7 -7
- package/.docs/raw/docs/ui/directive-text.mdx +3 -3
- package/.docs/raw/docs/ui/mcp-config.mdx +4 -4
- package/.docs/raw/docs/ui/mermaid.mdx +16 -9
- package/.docs/raw/docs/ui/part-grouping.mdx +84 -50
- package/.docs/raw/docs/ui/reasoning.mdx +4 -5
- package/.docs/raw/docs/ui/tool-fallback.mdx +16 -0
- package/.docs/raw/docs/ui/tool-group.mdx +5 -6
- package/.docs/raw/docs/utilities/heat-graph.mdx +1 -1
- package/.docs/raw/docs/utilities/react-o11y.mdx +2 -2
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/prepare-docs/code-examples.d.ts.map +1 -1
- package/dist/prepare-docs/code-examples.js.map +1 -1
- package/dist/prepare-docs/copy-raw.d.ts.map +1 -1
- package/dist/prepare-docs/copy-raw.js.map +1 -1
- package/dist/prepare-docs/prepare.js.map +1 -1
- package/dist/stdio.js.map +1 -1
- package/dist/tools/docs.js.map +1 -1
- package/dist/tools/examples.js.map +1 -1
- package/dist/tools/tests/test-setup.js.map +1 -1
- package/dist/utils/mdx.js.map +1 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js.map +1 -1
- package/package.json +5 -5
- package/.docs/organized/code-examples/with-parent-id-grouping.md +0 -596
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool-ui.mdx +0 -151
- package/.docs/raw/docs/(docs)/copilots/make-assistant-tool.mdx +0 -230
- package/.docs/raw/docs/guides/generative-ui.mdx +0 -142
- package/.docs/raw/docs/guides/tool-ui.mdx +0 -858
- package/.docs/raw/docs/guides/tools.mdx +0 -736
- /package/.docs/raw/docs/{(docs)/copilots → copilots}/assistant-frame.mdx +0 -0
- /package/.docs/raw/docs/{(docs)/copilots → copilots}/make-assistant-visible.mdx +0 -0
- /package/.docs/raw/docs/{(docs)/copilots → copilots}/use-assistant-instructions.mdx +0 -0
- /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/
|
|
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
|
-
├─
|
|
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
|
|
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
|
|
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
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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/
|
|
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
|
|
53
|
+
Configure rendering options in `mermaid-diagram.tsx`:
|
|
54
54
|
|
|
55
55
|
```tsx title="/components/assistant-ui/mermaid-diagram.tsx"
|
|
56
|
-
|
|
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
|
-
- **
|
|
64
|
-
- **
|
|
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
|
-
|
|
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
|
|
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`.
|
|
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={(
|
|
22
|
-
|
|
23
|
-
|
|
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
|
|
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
|
|
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={(
|
|
151
|
-
|
|
152
|
-
|
|
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={(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
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
|
|
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
|
|
350
|
+
type: "(part: PartState) => readonly `group-${string}`[]",
|
|
304
351
|
description:
|
|
305
|
-
"Maps a part to a group-key path. Return
|
|
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
|
|
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={(
|
|
395
|
-
|
|
396
|
-
|
|
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={(
|
|
51
|
-
|
|
52
|
-
|
|
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`
|
|
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={(
|
|
48
|
-
|
|
49
|
-
|
|
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
|
-
- **
|
|
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
|
-
|
|
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">;
|
package/dist/constants.js.map
CHANGED
|
@@ -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,
|
|
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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;cAca,MAAA,EAAM,SAGjB;AAAA,iBAeoB,SAAA,
|
|
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,
|
|
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,
|
|
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":";;;;;AAKA,MAAM,aAAa,KACjB,UACA,wDACF;AACA,MAAM,YAAY;AAOlB,eAAe,cACb,KACA,SACwB;CACxB,MAAM,QAAuB,CAAC;CAE9B,IAAI;EACF,MAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;EAE1D,KAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,WAAW,KAAK,KAAK,MAAM,IAAI;GAErC,IAAI,MAAM,YAAY;QAShB,CAAC;KAPH;KACA;KACA;KACA;KACA;KACA;IAEU,
|
|
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":";;;;;AAKA,MAAM,aAAa,KACjB,UACA,wDACF;AACA,MAAM,YAAY;AAOlB,eAAe,cACb,KACA,SACwB;CACxB,MAAM,QAAuB,CAAC;CAE9B,IAAI;EACF,MAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;EAE1D,KAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,WAAW,KAAK,KAAK,MAAM,IAAI;GAErC,IAAI,MAAM,YAAY;QAShB,CAAC;KAPH;KACA;KACA;KACA;KACA;KACA;IAEU,CAAC,CAAC,SAAS,MAAM,IAAI,GAAG;KAClC,MAAM,WAAW,MAAM,cAAc,UAAU,OAAO;KACtD,MAAM,KAAK,GAAG,QAAQ;IACxB;UACK,IAAI,MAAM,OAAO,GAAG;IACzB,MAAM,cAAc;KAClB;KACA;KACA;KACA;KACA;KACA;KACA;KACA;IACF;IACA,MAAM,MAAM,QAAQ,MAAM,IAAI,CAAC,CAAC,YAAY;IAE5C,IACE,YAAY,SAAS,GAAG,KACxB,MAAM,SAAS,kBACf,MAAM,SAAS,iBAEf,IAAI;KACF,MAAM,UAAU,MAAM,SAAS,UAAU,OAAO;KAChD,MAAM,eAAe,SAAS,SAAS,QAAQ;KAC/C,MAAM,KAAK;MAAE,MAAM;MAAc;KAAQ,CAAC;IAC5C,SAAS,OAAO;KACd,OAAO,KAAK,wBAAwB,YAAY,KAAK;IACvD;GAEJ;EACF;CACF,SAAS,OAAO;EACd,OAAO,MAAM,6BAA6B,OAAO,KAAK;CACxD;CAEA,OAAO;AACT;AAEA,SAAS,YAAY,UAA0B;CAY7C,OAAO;EATL,OAAO;EACP,QAAQ;EACR,OAAO;EACP,QAAQ;EACR,SAAS;EACT,QAAQ;EACR,OAAO;EACP,QAAQ;CAEE,EAXA,QAAQ,QAAQ,CAAC,CAAC,YAWd,MAAM;AACxB;AAEA,eAAsB,sBAAqC;CACzD,OAAO,KAAK,4BAA4B;CAExC,IAAI;EACF,MAAM,GAAG,YAAY;GAAE,WAAW;GAAM,OAAO;EAAK,CAAC;EACrD,MAAM,MAAM,YAAY,EAAE,WAAW,KAAK,CAAC;EAE3C,MAAM,cAAc,MAAM,QAAQ,eAAe,EAAE,eAAe,KAAK,CAAC;EAExE,KAAK,MAAM,OAAO,aAChB,IAAI,IAAI,YAAY,KAAK,CAAC,IAAI,KAAK,WAAW,GAAG,GAAG;GAClD,MAAM,cAAc,KAAK,eAAe,IAAI,IAAI;GAChD,OAAO,KAAK,uBAAuB,IAAI,MAAM;GAE7C,IAAI,cAAc;GAClB,IAAI;IACF,MAAM,kBAAkB,KAAK,aAAa,cAAc;IAIxD,cAHoB,KAAK,MACvB,MAAM,SAAS,iBAAiB,OAAO,CAEjB,CAAC,CAAC,eAAe;GAC3C,SAAS,OAAY;IACnB,IAAI,OAAO,SAAS,UAClB,OAAO,KAAK,mCAAmC,IAAI,KAAK,IAAI,KAAK;SAEjE,OAAO,MAAM,sCAAsC,IAAI,MAAM;GAEjE;GAEA,MAAM,QAAQ,MAAM,cAAc,aAAa,WAAW;GAE1D,MAAM,MAAM,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;GAEjD,IAAI,WAAW,cAAc,IAAI,KAAK;GACtC,IAAI,aACF,YAAY,GAAG,YAAY;GAG7B,IAAI,aAAa;GACjB,KAAK,MAAM,QAAQ,OAAO;IACxB,MAAM,QAAQ,KAAK,QAAQ,MAAM,IAAI,CAAC,CAAC;IACvC,IAAI,aAAa,QAAQ,WAAW;KAClC,YAAY;KACZ;IACF;IAGA,YAAY,MAAM,KAAK,KAAK,QAAQ,OAAO,GAAG,EAAE;IAChD,YAAY,SAAS,YAAY,KAAK,IAAI,EAAE;IAC5C,YAAY,KAAK;IACjB,YAAY;IAEZ,cAAc;GAChB;GAEA,MAAM,aAAa,KAAK,YAAY,GAAG,IAAI,KAAK,IAAI;GACpD,MAAM,UAAU,YAAY,UAAU,OAAO;GAC7C,OAAO,MAAM,oBAAoB,YAAY;EAC/C;EAGF,OAAO,KAAK,oCAAoC;CAClD,SAAS,OAAO;EACd,OAAO,MAAM,mCAAmC,KAAK;EACrD,MAAM;CACR;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copy-raw.d.ts","names":[],"sources":["../../src/prepare-docs/copy-raw.ts"],"mappings":";iBAkCsB,OAAA,
|
|
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,
|
|
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,
|
|
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"}
|