@mcp-b/react-components 0.37.0 → 0.39.0

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 (59) hide show
  1. package/dist/{AgentActivity-SP1WfLDW.d.ts → AgentActivity-Cc_oDYum.d.ts} +1 -1
  2. package/dist/Message-DBsHHhcM.d.ts +228 -0
  3. package/dist/{ThinkChat-DQh59CeC.js → ThinkChat-BES_3Mb-.js} +9 -4
  4. package/dist/{ThinkChatActivity-Dkmm2pIj.d.ts → ThinkChatActivity-D6-_5Phw.d.ts} +1 -1
  5. package/dist/{ThinkChatActivitySummary-teRjrPxW.d.ts → ThinkChatActivitySummary-BtBQgMg6.d.ts} +1 -1
  6. package/dist/{ToggleGroup-_pQMyHGM.d.ts → ToggleGroup-BrQZOQn_.d.ts} +1 -1
  7. package/dist/{WorkspaceFileView-Cu_ZG6HJ.js → WorkspaceFileView-D0r7xnq5.js} +3 -3
  8. package/dist/{WorkspaceLink-DQogVe8E.d.ts → WorkspaceLink-Bh9-Jo1r.d.ts} +1 -1
  9. package/dist/{WorkspaceLink-DZeLe_jN.js → WorkspaceLink-DtH66bAY.js} +4 -3
  10. package/dist/{WorkspaceMessageResponse-BWbkIELl.js → WorkspaceMessageResponse-CJCmGvTx.js} +64 -7
  11. package/dist/WorkspaceMessageResponse-Cy28WGSz.d.ts +24 -0
  12. package/dist/components/agents-sdk/AgentActivity.d.ts +1 -1
  13. package/dist/components/agents-sdk/AgentActivityPreview.d.ts +2 -2
  14. package/dist/components/agents-sdk/AgentActivityPreview.js +1 -1
  15. package/dist/components/agents-sdk/AgentChat.js +5 -5
  16. package/dist/components/agents-sdk/BrowserLiveView.d.ts +73 -25
  17. package/dist/components/agents-sdk/BrowserLiveView.js +95 -65
  18. package/dist/components/agents-sdk/BrowserRunPanel.js +1 -1
  19. package/dist/components/agents-sdk/McpPluginCatalog.js +1 -1
  20. package/dist/components/agents-sdk/ModelSelector.js +1 -1
  21. package/dist/components/agents-sdk/ThinkChat.d.ts +5 -2
  22. package/dist/components/agents-sdk/ThinkChat.js +1 -1
  23. package/dist/components/agents-sdk/ThinkChatActivity.d.ts +1 -1
  24. package/dist/components/agents-sdk/ThinkChatActivity.js +1 -1
  25. package/dist/components/agents-sdk/ThinkChatActivitySummary.d.ts +1 -1
  26. package/dist/components/agents-sdk/ThinkExecutionWorkbench.js +2 -2
  27. package/dist/components/agents-sdk/ThinkFullApp.d.ts +1 -1
  28. package/dist/components/agents-sdk/ThinkFullApp.js +11 -10
  29. package/dist/components/agents-sdk/ThinkFullAppViewSwitch.d.ts +1 -1
  30. package/dist/components/agents-sdk/ThinkFullAppViewSwitch.js +1 -1
  31. package/dist/components/agents-sdk/ThinkRoutineBrowser.js +1 -1
  32. package/dist/components/agents-sdk/ThinkRoutineDetail.js +1 -1
  33. package/dist/components/agents-sdk/ThinkRoutineForm.js +1 -1
  34. package/dist/components/agents-sdk/ThinkRoutineLibrary.js +2 -2
  35. package/dist/components/agents-sdk/ThinkRoutineRuns.js +1 -1
  36. package/dist/components/agents-sdk/ThinkThreadPicker.js +2 -2
  37. package/dist/components/agents-sdk/WorkspaceExplorer.d.ts +1 -1
  38. package/dist/components/agents-sdk/WorkspaceExplorer.js +2 -2
  39. package/dist/components/agents-sdk/WorkspaceFileView.js +1 -1
  40. package/dist/components/agents-sdk/WorkspaceLink.d.ts +1 -1
  41. package/dist/components/agents-sdk/WorkspaceLink.js +1 -1
  42. package/dist/components/agents-sdk/WorkspaceMessageResponse.d.ts +2 -12
  43. package/dist/components/agents-sdk/WorkspaceMessageResponse.js +1 -1
  44. package/dist/components/ai-sdk/Artifact.d.ts +44 -1
  45. package/dist/components/ai-sdk/Artifact.js +79 -3
  46. package/dist/components/ai-sdk/Message.d.ts +1 -227
  47. package/dist/components/foundations/EmptyState.d.ts +10 -0
  48. package/dist/components/foundations/EmptyState.js +10 -0
  49. package/dist/components/foundations/ToggleGroup.d.ts +1 -1
  50. package/dist/components/foundations/ToggleGroup.js +1 -1
  51. package/dist/components/general-purpose/PricingBillingToggle.js +1 -1
  52. package/dist/components/general-purpose/PricingUsageCalculator.js +1 -1
  53. package/dist/components/nanites/AgentToolDetail.js +3 -3
  54. package/dist/styles/agent-chat.css +2 -2
  55. package/dist/styles/artifact.css +65 -0
  56. package/dist/styles/base.css +4 -0
  57. package/dist/styles/browser-live-view.css +45 -0
  58. package/dist/styles/think-full-app.css +6 -0
  59. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import { n as WorkspaceDestination } from "./WorkspaceLink-DQogVe8E.js";
1
+ import { n as WorkspaceDestination } from "./WorkspaceLink-Bh9-Jo1r.js";
2
2
  import * as React from "react";
3
3
 
4
4
  //#region src/components/agents-sdk/AgentActivity.d.ts
@@ -0,0 +1,228 @@
1
+ import { n as IconButtonProps } from "./IconButton-BAUFhUk8.js";
2
+ import * as React from "react";
3
+ import { FileUIPart, UIMessage } from "ai";
4
+ import { StreamdownProps } from "streamdown";
5
+
6
+ //#region src/components/ai-sdk/Message.d.ts
7
+ type MessageRole = UIMessage["role"];
8
+ interface MessageProps extends React.HTMLAttributes<HTMLDivElement> {
9
+ /**
10
+ * The originating role of the message. Controls alignment and styling via
11
+ * the `data-from` attribute (e.g. user messages align end).
12
+ */
13
+ from?: MessageRole;
14
+ }
15
+ /**
16
+ * A chat message row. Aligns and styles itself based on {@link from}.
17
+ * Adapted from Vercel AI Elements and restyled with Sigvelo CSS tokens.
18
+ *
19
+ * Compose with {@link MessageContent} for the bubble, {@link MessageActions}
20
+ * for toolbar actions, and {@link MessageBranch} for multi-version responses.
21
+ *
22
+ * @example
23
+ * ```tsx
24
+ * <Message from="assistant">
25
+ * <MessageContent>Hello there!</MessageContent>
26
+ * <MessageActions>
27
+ * <MessageAction label="Copy" tooltip="Copy to clipboard">
28
+ * <CopyIcon />
29
+ * </MessageAction>
30
+ * </MessageActions>
31
+ * </Message>
32
+ * ```
33
+ *
34
+ * @see {@link https://elements.ai-sdk.dev/components/message | AI Elements Message}
35
+ */
36
+ declare function Message({
37
+ className,
38
+ from,
39
+ children,
40
+ ref,
41
+ ...props
42
+ }: MessageProps & {
43
+ ref?: React.Ref<HTMLDivElement>;
44
+ }): React.JSX.Element;
45
+ interface MessageContentProps extends React.HTMLAttributes<HTMLDivElement> {}
46
+ /**
47
+ * The visible bubble/body of a message. Styled differently based on the
48
+ * parent {@link Message}'s `from` attribute.
49
+ */
50
+ declare function MessageContent({
51
+ className,
52
+ children,
53
+ ref,
54
+ ...props
55
+ }: MessageContentProps & {
56
+ ref?: React.Ref<HTMLDivElement>;
57
+ }): React.JSX.Element;
58
+ type MessageResponseProps = StreamdownProps;
59
+ declare const MessageResponse: React.MemoExoticComponent<({
60
+ className,
61
+ components,
62
+ ...props
63
+ }: MessageResponseProps) => React.JSX.Element>;
64
+ interface MessageAttachmentProps extends Omit<React.HTMLAttributes<HTMLElement>, "color" | "part"> {
65
+ /** The AI SDK `file` part, taken whole. */
66
+ part: FileUIPart;
67
+ }
68
+ /**
69
+ * A `file` part inside a message: images render inline (click to zoom),
70
+ * anything else becomes a download chip. Covers both directions — files the
71
+ * user attached and files the agent emitted.
72
+ */
73
+ declare function MessageAttachment({
74
+ part,
75
+ className,
76
+ ...props
77
+ }: MessageAttachmentProps): React.JSX.Element;
78
+ interface MessageActionsProps extends React.HTMLAttributes<HTMLDivElement> {}
79
+ /**
80
+ * Horizontal list of action buttons (copy, retry, thumbs-up, etc.) shown
81
+ * alongside or beneath a message.
82
+ */
83
+ declare function MessageActions({
84
+ className,
85
+ children,
86
+ ref,
87
+ ...props
88
+ }: MessageActionsProps & {
89
+ ref?: React.Ref<HTMLDivElement>;
90
+ }): React.JSX.Element;
91
+ interface MessageActionProps extends Omit<IconButtonProps, "children"> {
92
+ children?: React.ReactNode;
93
+ }
94
+ /**
95
+ * A single icon button inside {@link MessageActions}. Always has an accessible
96
+ * name; shows a tooltip on hover/focus when {@link tooltip} is set.
97
+ */
98
+ declare function MessageAction({
99
+ className,
100
+ label,
101
+ tooltip,
102
+ variant,
103
+ color,
104
+ size,
105
+ children,
106
+ ref,
107
+ ...props
108
+ }: MessageActionProps & {
109
+ ref?: React.Ref<HTMLButtonElement>;
110
+ }): React.JSX.Element;
111
+ interface MessageToolbarProps extends React.HTMLAttributes<HTMLDivElement> {}
112
+ /**
113
+ * Horizontal container that places children in a row with space between —
114
+ * typically a {@link MessageBranchSelector} on one side and
115
+ * {@link MessageActions} on the other.
116
+ */
117
+ declare function MessageToolbar({
118
+ className,
119
+ children,
120
+ ref,
121
+ ...props
122
+ }: MessageToolbarProps & {
123
+ ref?: React.Ref<HTMLDivElement>;
124
+ }): React.JSX.Element;
125
+ interface MessageBranchProps extends React.HTMLAttributes<HTMLDivElement> {
126
+ /** Number of response branches rendered by MessageBranchContent. */
127
+ branchCount: number;
128
+ /** Zero-based index of the initially selected branch. */
129
+ defaultBranch?: number;
130
+ /** Controlled branch index. */
131
+ branch?: number;
132
+ /** Called when the selected branch changes. */
133
+ onBranchChange?: (branchIndex: number) => void;
134
+ }
135
+ /**
136
+ * Container for a message response with multiple versions. Tracks which
137
+ * branch is active and exposes navigation through {@link MessageBranchSelector},
138
+ * {@link MessageBranchPrevious}, {@link MessageBranchNext}, and {@link MessageBranchPage}.
139
+ */
140
+ declare function MessageBranch({
141
+ className,
142
+ branchCount,
143
+ defaultBranch,
144
+ branch,
145
+ onBranchChange,
146
+ children,
147
+ ref,
148
+ ...props
149
+ }: MessageBranchProps & {
150
+ ref?: React.Ref<HTMLDivElement>;
151
+ }): React.JSX.Element;
152
+ interface MessageBranchContentProps extends React.HTMLAttributes<HTMLDivElement> {}
153
+ /**
154
+ * Renders only the active branch's child. Expects siblings to represent
155
+ * alternative versions of the same response.
156
+ */
157
+ declare function MessageBranchContent({
158
+ className,
159
+ children,
160
+ ref,
161
+ ...props
162
+ }: MessageBranchContentProps & {
163
+ ref?: React.Ref<HTMLDivElement>;
164
+ }): React.JSX.Element;
165
+ interface MessageBranchSelectorProps extends React.HTMLAttributes<HTMLDivElement> {}
166
+ /**
167
+ * Inline group containing branch navigation controls (previous / page /
168
+ * next). Hidden automatically when there is only one branch.
169
+ */
170
+ declare function MessageBranchSelector({
171
+ className,
172
+ children,
173
+ ref,
174
+ ...props
175
+ }: MessageBranchSelectorProps & {
176
+ ref?: React.Ref<HTMLDivElement>;
177
+ }): React.JSX.Element | null;
178
+ interface MessageBranchPreviousProps extends Omit<IconButtonProps, "children" | "label"> {
179
+ label?: string;
180
+ children?: React.ReactNode;
181
+ }
182
+ /** Button that selects the previous branch. Disabled at the first branch. */
183
+ declare function MessageBranchPrevious({
184
+ className,
185
+ label,
186
+ variant,
187
+ color,
188
+ size,
189
+ children,
190
+ onClick,
191
+ ref,
192
+ ...props
193
+ }: MessageBranchPreviousProps & {
194
+ ref?: React.Ref<HTMLButtonElement>;
195
+ }): React.JSX.Element;
196
+ interface MessageBranchNextProps extends Omit<IconButtonProps, "children" | "label"> {
197
+ label?: string;
198
+ children?: React.ReactNode;
199
+ }
200
+ /** Button that selects the next branch. Disabled at the last branch. */
201
+ declare function MessageBranchNext({
202
+ className,
203
+ label,
204
+ variant,
205
+ color,
206
+ size,
207
+ children,
208
+ onClick,
209
+ ref,
210
+ ...props
211
+ }: MessageBranchNextProps & {
212
+ ref?: React.Ref<HTMLButtonElement>;
213
+ }): React.JSX.Element;
214
+ interface MessageBranchPageProps extends React.HTMLAttributes<HTMLSpanElement> {
215
+ /** Customize the displayed text. Defaults to `{index} / {count}`. */
216
+ format?: (currentIndex: number, total: number) => React.ReactNode;
217
+ }
218
+ /** Page indicator (e.g. "1 / 3") for the current branch selection. */
219
+ declare function MessageBranchPage({
220
+ className,
221
+ format,
222
+ ref,
223
+ ...props
224
+ }: MessageBranchPageProps & {
225
+ ref?: React.Ref<HTMLSpanElement>;
226
+ }): React.JSX.Element;
227
+ //#endregion
228
+ export { MessageResponse as C, MessageToolbarProps as D, MessageToolbar as E, MessageProps as S, MessageRole as T, MessageBranchProps as _, MessageActionsProps as a, MessageContent as b, MessageBranch as c, MessageBranchNext as d, MessageBranchNextProps as f, MessageBranchPreviousProps as g, MessageBranchPrevious as h, MessageActions as i, MessageBranchContent as l, MessageBranchPageProps as m, MessageAction as n, MessageAttachment as o, MessageBranchPage as p, MessageActionProps as r, MessageAttachmentProps as s, Message as t, MessageBranchContentProps as u, MessageBranchSelector as v, MessageResponseProps as w, MessageContentProps as x, MessageBranchSelectorProps as y };
@@ -1,11 +1,11 @@
1
1
  import { TransitionSurface } from "./components/foundations/TransitionSurface.js";
2
- import { AgentToolRunsProvider, useOptionalAgentToolRuns, useSourceScopedAgentToolEvents } from "./components/agents-sdk/AgentToolRunsContext.js";
3
2
  import { AgentChat, compactingNotice } from "./components/agents-sdk/AgentChat.js";
3
+ import { AgentToolRunsProvider, useOptionalAgentToolRuns, useSourceScopedAgentToolEvents } from "./components/agents-sdk/AgentToolRunsContext.js";
4
4
  import { SubagentRunList } from "./components/agents-sdk/SubagentRunList.js";
5
5
  import { ThinkChatContext, ThinkChatLiveContext, useOptionalThinkChatContext, useThinkChatContext } from "./components/agents-sdk/ThinkChatContext.js";
6
6
  import { ThinkChatActivity, createThinkChatActivityRenderer, renderThinkChatActivityPart } from "./components/agents-sdk/ThinkChatActivity.js";
7
7
  import { ThinkRecoveryNotice } from "./components/agents-sdk/ThinkRecoveryNotice.js";
8
- import { t as WorkspaceMessageResponse } from "./WorkspaceMessageResponse-BWbkIELl.js";
8
+ import { t as WorkspaceMessageResponse } from "./WorkspaceMessageResponse-CJCmGvTx.js";
9
9
  import * as React from "react";
10
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
11
  import { isTextUIPart } from "ai";
@@ -195,7 +195,7 @@ const ThinkChatApprovalsContext = React.createContext(null);
195
195
  * inside the log) or `excludeTools` + your own `renderPart` (standalone
196
196
  * card) — see README "App-specific tools" and the Custom Tool Panel story.
197
197
  */
198
- function ThinkChatMessages({ composerHeader, draft, loading, renderPart, excludeTools, renderAgentToolRunLink, toolRenderers, thinkStub, onExecutionSettled, pendingApprovals, notice, sessionCompaction, ...props }) {
198
+ function ThinkChatMessages({ composerHeader, draft, loading, renderPart, excludeTools, renderAgentToolRunLink, renderWorkspaceHtmlArtifact, toolRenderers, thinkStub, onExecutionSettled, pendingApprovals, notice, sessionCompaction, ...props }) {
199
199
  const chat = useOptionalThinkChatContext();
200
200
  const agentTools = useOptionalAgentToolRuns();
201
201
  const approvals = React.useContext(ThinkChatApprovalsContext);
@@ -224,9 +224,14 @@ function ThinkChatMessages({ composerHeader, draft, loading, renderPart, exclude
224
224
  return isTextUIPart(context.part) && context.part.text ? /* @__PURE__ */ jsx(WorkspaceMessageResponse, {
225
225
  animated: STREAMED_TEXT_ANIMATION,
226
226
  isAnimating: context.message.role === "assistant" && context.message.id === streamingMessageId && context.part.state === "streaming",
227
+ renderWorkspaceHtmlArtifact: context.message.role === "assistant" ? renderWorkspaceHtmlArtifact : void 0,
227
228
  children: context.part.text
228
229
  }) : void 0;
229
- }, [activityRenderPart, streamingMessageId]);
230
+ }, [
231
+ activityRenderPart,
232
+ renderWorkspaceHtmlArtifact,
233
+ streamingMessageId
234
+ ]);
230
235
  const resolvedRenderPart = React.useMemo(() => renderPart ? (context) => {
231
236
  const renderBuiltIn = () => {
232
237
  const builtIn = defaultRenderPart(context);
@@ -1,7 +1,7 @@
1
1
  import { i as AgentMessageRenderPartContext } from "./AgentMessageParts-C7L-Mv9U.js";
2
2
  import { r as AgentChatProps } from "./AgentChat-CVO7xyLC.js";
3
3
  import { l as ThinkChatPart } from "./ThinkChatToolParts-D4qcnnxt.js";
4
- import { t as ThinkChatActivityDescription } from "./ThinkChatActivitySummary-teRjrPxW.js";
4
+ import { t as ThinkChatActivityDescription } from "./ThinkChatActivitySummary-BtBQgMg6.js";
5
5
  import * as React from "react";
6
6
  import { DynamicToolUIPart, ToolUIPart, UIMessage } from "ai";
7
7
  import { AgentToolRunState } from "agents/agent-tools";
@@ -1,4 +1,4 @@
1
- import { i as AgentActivityIconKind, s as AgentActivitySummary } from "./AgentActivity-SP1WfLDW.js";
1
+ import { i as AgentActivityIconKind, s as AgentActivitySummary } from "./AgentActivity-Cc_oDYum.js";
2
2
  import { l as ThinkChatPart } from "./ThinkChatToolParts-D4qcnnxt.js";
3
3
  import { DynamicToolUIPart, ToolUIPart } from "ai";
4
4
 
@@ -1,7 +1,7 @@
1
1
  import { r as ToggleVariantsOptions } from "./Toggle-DLrIf5YH.js";
2
2
  import * as React from "react";
3
- import { Toggle } from "@base-ui/react/toggle";
4
3
  import { ToggleGroup } from "@base-ui/react/toggle-group";
4
+ import { Toggle } from "@base-ui/react/toggle";
5
5
 
6
6
  //#region src/components/foundations/ToggleGroup.d.ts
7
7
  type ToggleGroupSize = ToggleVariantsOptions["size"];
@@ -1,10 +1,10 @@
1
1
  import { A as MaximizeIcon, d as CheckIcon, h as CodeIcon, r as ArrowLeftIcon, tt as WarningIcon, x as EyeIcon, y as DownloadIcon } from "./icons-B4mGvCvc.js";
2
2
  import { r as formatClock } from "./format-DB2mX9DA.js";
3
3
  import { a as CodeBlockCopyButton, i as CodeBlockContent, r as CodeBlockContainer, t as CodeBlock } from "./CodeBlock-DO4Hdu1R.js";
4
- import { AppTopBar } from "./components/general-purpose/AppTopBar.js";
5
4
  import { inferWorkspaceLanguage, inferWorkspaceMedia, isWorkspaceMarkdownPath, isWorkspaceSkillPath, parseWorkspaceSkill } from "./components/agents-sdk/WorkspaceFile.js";
6
- import { c as useWorkspaceNavigationContext, s as useWorkspaceNavigationRestoration } from "./WorkspaceLink-DZeLe_jN.js";
7
- import { n as createWorkspaceRehypePlugins, t as WorkspaceMessageResponse } from "./WorkspaceMessageResponse-BWbkIELl.js";
5
+ import { c as useWorkspaceNavigationContext, s as useWorkspaceNavigationRestoration } from "./WorkspaceLink-DtH66bAY.js";
6
+ import { n as createWorkspaceRehypePlugins, t as WorkspaceMessageResponse } from "./WorkspaceMessageResponse-CJCmGvTx.js";
7
+ import { AppTopBar } from "./components/general-purpose/AppTopBar.js";
8
8
  import { WorkspaceHeader } from "./components/agents-sdk/WorkspaceHeader.js";
9
9
  import * as React from "react";
10
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -76,7 +76,7 @@ declare function WorkspaceFileLink({
76
76
  className,
77
77
  download,
78
78
  href,
79
- node: _node,
79
+ node,
80
80
  onClick,
81
81
  rel,
82
82
  target,
@@ -233,11 +233,12 @@ function UnavailableWorkspaceLink({ children, className }) {
233
233
  * Markdown-compatible anchor that resolves local files through the nearest
234
234
  * workspace navigation provider while preserving native link behavior.
235
235
  */
236
- function WorkspaceFileLink({ children, className, download, href = "", node: _node, onClick, rel, target, ...props }) {
236
+ function WorkspaceFileLink({ children, className, download, href = "", node, onClick, rel, target, ...props }) {
237
237
  const workspace = useWorkspaceNavigationContext();
238
238
  const restoration = useWorkspaceNavigationRestoration();
239
239
  if (!workspace) return /* @__PURE__ */ jsx("a", {
240
240
  className,
241
+ "data-streamdown": node ? "link" : void 0,
241
242
  download,
242
243
  href,
243
244
  onClick,
@@ -259,7 +260,7 @@ function WorkspaceFileLink({ children, className, download, href = "", node: _no
259
260
  const externalTarget = target ?? "_blank";
260
261
  return /* @__PURE__ */ jsxs("a", {
261
262
  className: cx("workspace-link workspace-link--external", className),
262
- "data-streamdown": "link",
263
+ "data-streamdown": node ? "link" : void 0,
263
264
  download,
264
265
  href: resolved.href,
265
266
  onClick,
@@ -285,7 +286,7 @@ function WorkspaceFileLink({ children, className, download, href = "", node: _no
285
286
  return /* @__PURE__ */ jsx(NavigationLink, {
286
287
  render: workspace.navigation.renderLink(resolved),
287
288
  className: cx("workspace-link workspace-link--file", className),
288
- "data-streamdown": "link",
289
+ "data-streamdown": node ? "link" : void 0,
289
290
  "data-workspace-link": "file",
290
291
  "data-workspace-destination-fragment": resolved.fragment ?? "",
291
292
  "data-workspace-path": resolved.path,
@@ -1,7 +1,7 @@
1
1
  import { MessageResponse } from "./components/ai-sdk/Message.js";
2
- import { c as useWorkspaceNavigationContext, r as resolveWorkspaceLink, t as WorkspaceFileLink } from "./WorkspaceLink-DZeLe_jN.js";
2
+ import { c as useWorkspaceNavigationContext, r as resolveWorkspaceLink, t as WorkspaceFileLink } from "./WorkspaceLink-DtH66bAY.js";
3
3
  import * as React from "react";
4
- import { jsx } from "react/jsx-runtime";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
5
  import { defaultRehypePlugins } from "streamdown";
6
6
  import { visit } from "unist-util-visit";
7
7
  //#region src/components/_internal/workspace-markdown.ts
@@ -84,17 +84,74 @@ const workspaceComponents = {
84
84
  a: WorkspaceFileLink
85
85
  };
86
86
  /** Adds workspace-aware Markdown links when rendered inside a workspace provider. */
87
- const WorkspaceMessageResponse = React.memo(function WorkspaceMessageResponse({ components, rehypePlugins, ...props }) {
87
+ const WorkspaceMessageResponse = React.memo(function WorkspaceMessageResponse({ components, rehypePlugins, renderWorkspaceHtmlArtifact, ...props }) {
88
88
  const workspace = useWorkspaceNavigationContext();
89
89
  const resolvedRehypePlugins = React.useMemo(() => rehypePlugins ?? (workspace ? createWorkspaceRehypePlugins(workspace.root, workspace.base) : void 0), [rehypePlugins, workspace]);
90
90
  return /* @__PURE__ */ jsx(MessageResponse, {
91
- components: components ? {
92
- ...workspaceComponents,
93
- ...components
94
- } : workspaceComponents,
91
+ components: React.useMemo(() => {
92
+ const merged = components ? {
93
+ ...workspaceComponents,
94
+ ...components
95
+ } : workspaceComponents;
96
+ if (!workspace || !renderWorkspaceHtmlArtifact) return merged;
97
+ const FallbackParagraph = components?.p ?? "p";
98
+ return {
99
+ ...merged,
100
+ p: function WorkspaceHtmlArtifactParagraph({ node, children, ...paragraphProps }) {
101
+ const renderFallbackParagraph = (content) => React.createElement(FallbackParagraph, typeof FallbackParagraph === "string" ? paragraphProps : {
102
+ node,
103
+ ...paragraphProps
104
+ }, content);
105
+ const artifact = getWorkspaceHtmlArtifactParagraph(node, workspace.root, workspace.base);
106
+ if (!artifact) return renderFallbackParagraph(children);
107
+ const remainingChildren = React.Children.toArray(children).filter((_child, index) => index !== artifact.childIndex);
108
+ return /* @__PURE__ */ jsxs(Fragment, { children: [artifact.showRemainingChildren ? renderFallbackParagraph(remainingChildren) : null, renderWorkspaceHtmlArtifact({
109
+ label: artifact.label,
110
+ path: artifact.path,
111
+ sourceLink: /* @__PURE__ */ jsx(WorkspaceFileLink, { href: artifact.path })
112
+ })] });
113
+ }
114
+ };
115
+ }, [
116
+ components,
117
+ renderWorkspaceHtmlArtifact,
118
+ workspace
119
+ ]),
95
120
  rehypePlugins: resolvedRehypePlugins,
96
121
  ...props
97
122
  });
98
123
  });
124
+ function getWorkspaceHtmlArtifactParagraph(node, root, base) {
125
+ if (!node || node.tagName !== "p") return null;
126
+ const children = node.children;
127
+ const matches = children.flatMap((child, childIndex) => {
128
+ if (child.type !== "element" || child.tagName !== "a") return [];
129
+ const href = child.properties?.href;
130
+ if (typeof href !== "string") return [];
131
+ const destination = resolveWorkspaceLink({
132
+ href,
133
+ root,
134
+ base
135
+ });
136
+ if (destination.kind !== "file" || destination.fragment !== null || !destination.path.toLowerCase().endsWith(".html")) return [];
137
+ return [{
138
+ anchor: child,
139
+ childIndex,
140
+ path: destination.path
141
+ }];
142
+ });
143
+ if (matches.length !== 1) return null;
144
+ const [{ anchor, childIndex, path }] = matches;
145
+ return {
146
+ childIndex,
147
+ path,
148
+ label: markdownText(anchor).trim() || path.split("/").at(-1) || "Interactive UI",
149
+ showRemainingChildren: children.some((child, index) => index !== childIndex && (child.type !== "text" || child.value.trim()))
150
+ };
151
+ }
152
+ function markdownText(node) {
153
+ if (node.type === "text") return node.value;
154
+ return node.type === "element" ? node.children.map(markdownText).join("") : "";
155
+ }
99
156
  //#endregion
100
157
  export { createWorkspaceRehypePlugins as n, WorkspaceMessageResponse as t };
@@ -0,0 +1,24 @@
1
+ import { w as MessageResponseProps } from "./Message-DBsHHhcM.js";
2
+ import * as React from "react";
3
+
4
+ //#region src/components/agents-sdk/WorkspaceMessageResponse.d.ts
5
+ interface WorkspaceHtmlArtifactRenderInput {
6
+ label: string;
7
+ path: string;
8
+ /** Shared workspace link element; hosts pass it through to the preview unchanged. */
9
+ sourceLink: React.ReactElement;
10
+ }
11
+ type WorkspaceHtmlArtifactRenderer = (artifact: WorkspaceHtmlArtifactRenderInput) => React.ReactNode;
12
+ interface WorkspaceMessageResponseProps extends MessageResponseProps {
13
+ /** Promotes one standalone workspace HTML link into host-hydrated shared UI. */
14
+ renderWorkspaceHtmlArtifact?: WorkspaceHtmlArtifactRenderer;
15
+ }
16
+ /** Adds workspace-aware Markdown links when rendered inside a workspace provider. */
17
+ declare const WorkspaceMessageResponse: React.MemoExoticComponent<({
18
+ components,
19
+ rehypePlugins,
20
+ renderWorkspaceHtmlArtifact,
21
+ ...props
22
+ }: WorkspaceMessageResponseProps) => React.JSX.Element>;
23
+ //#endregion
24
+ export { WorkspaceMessageResponseProps as i, WorkspaceHtmlArtifactRenderer as n, WorkspaceMessageResponse as r, WorkspaceHtmlArtifactRenderInput as t };
@@ -1,2 +1,2 @@
1
- import { a as AgentActivityIconProps, i as AgentActivityIconKind, n as AgentActivityFaviconProps, o as AgentActivityMode, r as AgentActivityIcon, s as AgentActivitySummary, t as AgentActivityFavicon } from "../../AgentActivity-SP1WfLDW.js";
1
+ import { a as AgentActivityIconProps, i as AgentActivityIconKind, n as AgentActivityFaviconProps, o as AgentActivityMode, r as AgentActivityIcon, s as AgentActivitySummary, t as AgentActivityFavicon } from "../../AgentActivity-Cc_oDYum.js";
2
2
  export { AgentActivityFavicon, AgentActivityFaviconProps, AgentActivityIcon, AgentActivityIconKind, AgentActivityIconProps, AgentActivityMode, AgentActivitySummary };
@@ -1,5 +1,5 @@
1
- import { n as WorkspaceDestination } from "../../WorkspaceLink-DQogVe8E.js";
2
- import { s as AgentActivitySummary } from "../../AgentActivity-SP1WfLDW.js";
1
+ import { n as WorkspaceDestination } from "../../WorkspaceLink-Bh9-Jo1r.js";
2
+ import { s as AgentActivitySummary } from "../../AgentActivity-Cc_oDYum.js";
3
3
  import * as React from "react";
4
4
 
5
5
  //#region src/components/agents-sdk/AgentActivityPreview.d.ts
@@ -2,9 +2,9 @@ import { t as cx } from "../../class-names-BiMDVpUo.js";
2
2
  import { C as FileIcon, J as SpinnerIcon, j as McpIcon, rt as XIcon, tt as WarningIcon } from "../../icons-B4mGvCvc.js";
3
3
  import { ActivityHeader } from "../ai-sdk/Activity.js";
4
4
  import { Button } from "../foundations/Button.js";
5
- import { AppIcon } from "../foundations/AppIcon.js";
6
5
  import { t as NavigationLink } from "../../navigation-link-kqMa81v5.js";
7
6
  import { AgentActivityFavicon, AgentActivityIcon } from "./AgentActivity.js";
7
+ import { AppIcon } from "../foundations/AppIcon.js";
8
8
  import "react";
9
9
  import { jsx, jsxs } from "react/jsx-runtime";
10
10
  //#region src/components/agents-sdk/AgentActivityPreview.tsx
@@ -666,13 +666,13 @@ function AgentChat({ className, messages, status = "ready", onSubmit, showCompos
666
666
  "aria-atomic": "true",
667
667
  children: copyAnnouncement
668
668
  }),
669
- loading ? /* @__PURE__ */ jsxs("div", {
669
+ loading ? /* @__PURE__ */ jsx("div", {
670
670
  className: "agent-chat__transcript-loading",
671
671
  role: "status",
672
- children: [/* @__PURE__ */ jsx(SpinnerIcon, {}), /* @__PURE__ */ jsx("span", {
673
- className: "sigvelo-visually-hidden",
674
- children: "Loading conversation"
675
- })]
672
+ children: /* @__PURE__ */ jsx(EmptyState, {
673
+ icon: /* @__PURE__ */ jsx(SpinnerIcon, {}),
674
+ description: "Loading conversation"
675
+ })
676
676
  }) : showsStartScreen ? /* @__PURE__ */ jsx(AgentChatStartScreen, {
677
677
  ...startScreenProps,
678
678
  composer
@@ -2,27 +2,85 @@ import * as React from "react";
2
2
  import { BrowserLiveViewUrl } from "agents/browser";
3
3
 
4
4
  //#region src/components/agents-sdk/BrowserLiveView.d.ts
5
- interface BrowserLiveViewProps extends React.HTMLAttributes<HTMLDivElement> {
6
- /** Complete upstream value returned by `cdp.getLiveViewUrl()`. */
7
- source: BrowserLiveViewUrl;
8
- /** Epoch ms when `source` was received. Defaults to its first render. */
9
- receivedAt?: number;
10
- /** The page the session was showing — used for the ended-state text. */
5
+ /** Where a live view is in its lifecycle, however the pixels arrive. */
6
+ type BrowserLiveViewPhase = "connecting" | "streaming" | "reconnecting" | "idle" | "failed";
7
+ interface BrowserLiveViewCommonProps extends React.HTMLAttributes<HTMLDivElement> {
8
+ /** The page being shown names the surface and labels its ended state. */
11
9
  pageTitle?: string;
12
10
  /**
13
- * Shown once the link expires pass the last screenshot the agent took
11
+ * Replaces the built-in text for the current phase e.g. a failure reason.
12
+ * Set it while the view is live and it reads as a notice over the picture,
13
+ * which is where a fault that does not end the session belongs.
14
+ */
15
+ statusLabel?: string;
16
+ /**
17
+ * Shown once the view stops — pass the last screenshot the agent took
14
18
  * (`<img>`) to keep the final frame on screen. Defaults to a quiet
15
19
  * "Live view ended" state.
16
20
  */
17
21
  fallback?: React.ReactNode;
22
+ /** Omits the expand control for a view that already fills its viewport. */
23
+ expandable?: boolean;
24
+ /**
25
+ * Takes the whole container instead of standing in it as a 16/10 card.
26
+ * The card treatment — the aspect box, the hairline, the rounded corners —
27
+ * is there to separate the view from what sits beside it; a view that is
28
+ * the entire surface, as it is on a phone, has nothing to separate from and
29
+ * spends real pixels saying so. Usually paired with `expandable={false}`,
30
+ * since there is nowhere larger to expand into.
31
+ */
32
+ fill?: boolean;
18
33
  }
34
+ type BrowserLiveViewProps = BrowserLiveViewCommonProps & ({
35
+ /** Complete upstream value returned by `cdp.getLiveViewUrl()`. */source: BrowserLiveViewUrl; /** Epoch ms when `source` was received. Defaults to its first render. */
36
+ receivedAt?: number;
37
+ renderMedia?: never;
38
+ phase?: never;
39
+ } | {
40
+ /**
41
+ * The picture, drawn by the host — a `<video>` on its own transport, a
42
+ * canvas, whatever it carries. Called once per placement because
43
+ * neither a video nor an iframe can occupy two places at once.
44
+ *
45
+ * Remote-control surfaces belong in here too: coordinate mapping and
46
+ * key handling are the host's, since only it knows what its input API
47
+ * expects. This component owns the frame around them. An overlay drawn
48
+ * here covers the picture and stays under the frame's own chrome, so a
49
+ * control surface can take every pointer the picture gets without
50
+ * swallowing the Live badge or the expand control.
51
+ *
52
+ * `statusId` names whatever element currently states the phase, for a
53
+ * control surface to point `aria-describedby` at.
54
+ */
55
+ renderMedia: (placement: "inline" | "dialog", statusId: string) => React.ReactNode; /** The host draws, so the host owns the lifecycle. A URL derives its own. */
56
+ phase: BrowserLiveViewPhase;
57
+ source?: never;
58
+ receivedAt?: never;
59
+ });
19
60
  /**
20
- * Embeds a Browser Run Live View — a real-time, interactive view of the
21
- * agent's browser session. Links expire (~5 minutes), so the iframe swaps to
22
- * `fallback` (e.g. the last screenshot) once `source.expiresInMs` passes.
23
- * While the hosted viewer connects, a quiet loading overlay hides the frame; if it
24
- * never loads, the view degrades to `fallback` or an unavailable state. An
25
- * expand button opens the same view in a fullscreen dialog.
61
+ * A live, interactive view of an agent's browser session.
62
+ *
63
+ * It takes the session either way round. Give it `source` — a Browser Run
64
+ * `BrowserLiveViewUrl` — and it embeds the hosted viewer, expiring the frame
65
+ * on its own once `expiresInMs` passes. Give it `renderMedia` and a `phase`
66
+ * instead and the host draws the picture on its own transport while this keeps
67
+ * the frame around it. The Live badge, the connecting overlay, the ended
68
+ * state, and the fullscreen expand are the same either way, because to the
69
+ * person watching it is the same thing.
70
+ *
71
+ * `fill` drops the card treatment for a view that is the whole surface rather
72
+ * than a block on one — the phone's screen, or a panel that already sizes
73
+ * itself. Everything else about the frame is unchanged.
74
+ *
75
+ * A host-drawn view keeps its own input surface, because coordinate mapping
76
+ * and key handling depend on what the host's input API expects — a screencast
77
+ * wants CSS pixels offset by its viewport, and nothing generic here could know
78
+ * that. This component owns the frame; the host owns the picture and control.
79
+ *
80
+ * The two sources differ in what the host must trust. A hosted URL embeds a
81
+ * third-party origin and runs its script; the iframe is unsandboxed by design
82
+ * because the viewer needs scripts and its own origin to stream the session,
83
+ * so only pass trusted Live View URLs. Host-drawn media embeds no origin.
26
84
  *
27
85
  * Where URLs come from (upstream: `agents/browser` in
28
86
  * github.com/cloudflare/agents — `BrowserLiveViewUrl`): the model calls
@@ -32,17 +90,7 @@ interface BrowserLiveViewProps extends React.HTMLAttributes<HTMLDivElement> {
32
90
  *
33
91
  * Styling rides `@mcp-b/react-components/styles` (browser-live-view.css),
34
92
  * which think-chat consumers load anyway.
35
- *
36
- * The iframe is unsandboxed by design: the hosted Live View UI needs scripts
37
- * and its own origin to stream the session. Only pass trusted Live View URLs.
38
93
  */
39
- declare function BrowserLiveView({
40
- source,
41
- receivedAt,
42
- pageTitle,
43
- fallback,
44
- className,
45
- ...props
46
- }: BrowserLiveViewProps): React.JSX.Element;
94
+ declare function BrowserLiveView(props: BrowserLiveViewProps): React.JSX.Element;
47
95
  //#endregion
48
- export { BrowserLiveView, BrowserLiveViewProps };
96
+ export { BrowserLiveView, BrowserLiveViewPhase, BrowserLiveViewProps };