dreamboard 0.1.21 → 0.1.23

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 (186) hide show
  1. package/dist/{chunk-EYYWGWTO.js → chunk-2RCUHMGL.js} +343 -1911
  2. package/dist/chunk-2RCUHMGL.js.map +1 -0
  3. package/dist/{chunk-MOVHYB6E.js → chunk-GN7232BY.js} +1025 -695
  4. package/dist/chunk-GN7232BY.js.map +1 -0
  5. package/dist/{chunk-BMYC6772.js → chunk-H3O43F5P.js} +9765 -3068
  6. package/dist/chunk-H3O43F5P.js.map +1 -0
  7. package/dist/dev-host/dev-api-proxy-plugin.ts +330 -0
  8. package/dist/dev-host/dev-diagnostics.ts +62 -0
  9. package/dist/dev-host/dev-fallback-stylesheet.ts +50 -0
  10. package/dist/dev-host/dev-host-controller.ts +686 -0
  11. package/dist/dev-host/dev-host-player-query.ts +17 -0
  12. package/dist/dev-host/dev-host-session-transport.ts +52 -0
  13. package/dist/dev-host/dev-host-storage.ts +56 -0
  14. package/dist/dev-host/dev-log-relay-plugin.ts +469 -0
  15. package/dist/dev-host/dev-runtime-config.ts +14 -0
  16. package/dist/dev-host/dev-runtime-platform.ts +419 -0
  17. package/dist/dev-host/dev-virtual-modules-plugin.ts +63 -0
  18. package/dist/dev-host/host-main.css +182 -0
  19. package/dist/dev-host/host-main.tsx +754 -0
  20. package/dist/dev-host/index.html +56 -0
  21. package/dist/dev-host/plugin-main.ts +55 -0
  22. package/dist/dev-host/plugin.html +24 -0
  23. package/dist/dev-host/start-dev-server.ts +138 -0
  24. package/dist/dev-host/virtual-modules.d.ts +27 -0
  25. package/dist/dist-FEPN3BDN.js +16543 -0
  26. package/dist/dist-FEPN3BDN.js.map +1 -0
  27. package/dist/{dist-WJRJNFLI.js → dist-FRURQI7Q.js} +4 -2
  28. package/dist/index.js +3 -3
  29. package/dist/internal.js +159 -124
  30. package/dist/internal.js.map +1 -1
  31. package/dist/runtime-packages/tailwind-config/shared-styles.css +146 -0
  32. package/dist/runtime-packages/ui/src/components/.gitkeep +0 -0
  33. package/dist/runtime-packages/ui/src/components/accordion.tsx +66 -0
  34. package/dist/runtime-packages/ui/src/components/ai-elements/actions.tsx +65 -0
  35. package/dist/runtime-packages/ui/src/components/ai-elements/artifact.tsx +147 -0
  36. package/dist/runtime-packages/ui/src/components/ai-elements/branch.tsx +215 -0
  37. package/dist/runtime-packages/ui/src/components/ai-elements/canvas.tsx +22 -0
  38. package/dist/runtime-packages/ui/src/components/ai-elements/chain-of-thought.tsx +228 -0
  39. package/dist/runtime-packages/ui/src/components/ai-elements/code-block.tsx +179 -0
  40. package/dist/runtime-packages/ui/src/components/ai-elements/confirmation.tsx +158 -0
  41. package/dist/runtime-packages/ui/src/components/ai-elements/connection.tsx +28 -0
  42. package/dist/runtime-packages/ui/src/components/ai-elements/context.tsx +408 -0
  43. package/dist/runtime-packages/ui/src/components/ai-elements/controls.tsx +18 -0
  44. package/dist/runtime-packages/ui/src/components/ai-elements/conversation.tsx +97 -0
  45. package/dist/runtime-packages/ui/src/components/ai-elements/edge.tsx +140 -0
  46. package/dist/runtime-packages/ui/src/components/ai-elements/image.tsx +24 -0
  47. package/dist/runtime-packages/ui/src/components/ai-elements/inline-citation.tsx +287 -0
  48. package/dist/runtime-packages/ui/src/components/ai-elements/loader.tsx +96 -0
  49. package/dist/runtime-packages/ui/src/components/ai-elements/message.tsx +463 -0
  50. package/dist/runtime-packages/ui/src/components/ai-elements/node.tsx +71 -0
  51. package/dist/runtime-packages/ui/src/components/ai-elements/open-in-chat.tsx +365 -0
  52. package/dist/runtime-packages/ui/src/components/ai-elements/panel.tsx +15 -0
  53. package/dist/runtime-packages/ui/src/components/ai-elements/plan.tsx +142 -0
  54. package/dist/runtime-packages/ui/src/components/ai-elements/prompt-input.tsx +1380 -0
  55. package/dist/runtime-packages/ui/src/components/ai-elements/queue.tsx +274 -0
  56. package/dist/runtime-packages/ui/src/components/ai-elements/reasoning.tsx +182 -0
  57. package/dist/runtime-packages/ui/src/components/ai-elements/response.tsx +22 -0
  58. package/dist/runtime-packages/ui/src/components/ai-elements/shimmer.tsx +64 -0
  59. package/dist/runtime-packages/ui/src/components/ai-elements/sources.tsx +77 -0
  60. package/dist/runtime-packages/ui/src/components/ai-elements/suggestion.tsx +53 -0
  61. package/dist/runtime-packages/ui/src/components/ai-elements/task.tsx +87 -0
  62. package/dist/runtime-packages/ui/src/components/ai-elements/tool.tsx +165 -0
  63. package/dist/runtime-packages/ui/src/components/ai-elements/toolbar.tsx +16 -0
  64. package/dist/runtime-packages/ui/src/components/ai-elements/web-preview.tsx +263 -0
  65. package/dist/runtime-packages/ui/src/components/alert-dialog.tsx +157 -0
  66. package/dist/runtime-packages/ui/src/components/alert.tsx +66 -0
  67. package/dist/runtime-packages/ui/src/components/avatar.tsx +53 -0
  68. package/dist/runtime-packages/ui/src/components/badge.tsx +46 -0
  69. package/dist/runtime-packages/ui/src/components/button-group.tsx +83 -0
  70. package/dist/runtime-packages/ui/src/components/button.tsx +65 -0
  71. package/dist/runtime-packages/ui/src/components/card.tsx +92 -0
  72. package/dist/runtime-packages/ui/src/components/carousel.tsx +241 -0
  73. package/dist/runtime-packages/ui/src/components/collapsible.tsx +33 -0
  74. package/dist/runtime-packages/ui/src/components/command.tsx +184 -0
  75. package/dist/runtime-packages/ui/src/components/context-menu.tsx +252 -0
  76. package/dist/runtime-packages/ui/src/components/counter.tsx +11 -0
  77. package/dist/runtime-packages/ui/src/components/dialog.tsx +146 -0
  78. package/dist/runtime-packages/ui/src/components/drawer.tsx +132 -0
  79. package/dist/runtime-packages/ui/src/components/dropdown-menu.tsx +257 -0
  80. package/dist/runtime-packages/ui/src/components/form.tsx +168 -0
  81. package/dist/runtime-packages/ui/src/components/header.tsx +13 -0
  82. package/dist/runtime-packages/ui/src/components/hover-card.tsx +44 -0
  83. package/dist/runtime-packages/ui/src/components/input-group.tsx +178 -0
  84. package/dist/runtime-packages/ui/src/components/input.tsx +21 -0
  85. package/dist/runtime-packages/ui/src/components/item.tsx +193 -0
  86. package/dist/runtime-packages/ui/src/components/label.tsx +24 -0
  87. package/dist/runtime-packages/ui/src/components/navigation-menu.tsx +168 -0
  88. package/dist/runtime-packages/ui/src/components/popover.tsx +55 -0
  89. package/dist/runtime-packages/ui/src/components/progress.tsx +31 -0
  90. package/dist/runtime-packages/ui/src/components/radio-group.tsx +45 -0
  91. package/dist/runtime-packages/ui/src/components/resizable.tsx +56 -0
  92. package/dist/runtime-packages/ui/src/components/scroll-area.tsx +58 -0
  93. package/dist/runtime-packages/ui/src/components/select.tsx +187 -0
  94. package/dist/runtime-packages/ui/src/components/separator.tsx +28 -0
  95. package/dist/runtime-packages/ui/src/components/skeleton.tsx +13 -0
  96. package/dist/runtime-packages/ui/src/components/sonner.tsx +25 -0
  97. package/dist/runtime-packages/ui/src/components/spinner.tsx +16 -0
  98. package/dist/runtime-packages/ui/src/components/switch.tsx +31 -0
  99. package/dist/runtime-packages/ui/src/components/table.tsx +137 -0
  100. package/dist/runtime-packages/ui/src/components/tabs.tsx +74 -0
  101. package/dist/runtime-packages/ui/src/components/textarea.tsx +23 -0
  102. package/dist/runtime-packages/ui/src/components/theme-provider.tsx +73 -0
  103. package/dist/runtime-packages/ui/src/components/tooltip.tsx +61 -0
  104. package/dist/runtime-packages/ui/src/components/ui/file-upload.tsx +195 -0
  105. package/dist/runtime-packages/ui/src/hooks/.gitkeep +0 -0
  106. package/dist/runtime-packages/ui/src/index.ts +68 -0
  107. package/dist/runtime-packages/ui/src/lib/utils.ts +6 -0
  108. package/dist/runtime-packages/ui-host-runtime/src/actor-principal.ts +68 -0
  109. package/dist/runtime-packages/ui-host-runtime/src/components/host-controls.tsx +359 -0
  110. package/dist/runtime-packages/ui-host-runtime/src/components/host-feedback-toaster.tsx +274 -0
  111. package/dist/runtime-packages/ui-host-runtime/src/components/host-feedback.tsx +214 -0
  112. package/dist/runtime-packages/ui-host-runtime/src/components/host-session-metadata.tsx +135 -0
  113. package/dist/runtime-packages/ui-host-runtime/src/components/index.ts +5 -0
  114. package/dist/runtime-packages/ui-host-runtime/src/components/perf-overlay.tsx +194 -0
  115. package/dist/runtime-packages/ui-host-runtime/src/host-controls.tsx +1 -0
  116. package/dist/runtime-packages/ui-host-runtime/src/host-feedback.tsx +1 -0
  117. package/dist/runtime-packages/ui-host-runtime/src/host-session-transport.ts +162 -0
  118. package/dist/runtime-packages/ui-host-runtime/src/index.ts +2 -0
  119. package/dist/runtime-packages/ui-host-runtime/src/logger.ts +11 -0
  120. package/dist/runtime-packages/ui-host-runtime/src/perf.ts +253 -0
  121. package/dist/runtime-packages/ui-host-runtime/src/plugin-bridge.ts +195 -0
  122. package/dist/runtime-packages/ui-host-runtime/src/plugin-health-check.ts +138 -0
  123. package/dist/runtime-packages/ui-host-runtime/src/plugin-messages.ts +159 -0
  124. package/dist/runtime-packages/ui-host-runtime/src/plugin-session-gateway.ts +524 -0
  125. package/dist/runtime-packages/ui-host-runtime/src/runtime/index.ts +12 -0
  126. package/dist/runtime-packages/ui-host-runtime/src/screenshot/projection-to-snapshot.ts +122 -0
  127. package/dist/runtime-packages/ui-host-runtime/src/screenshot/static-store-api.ts +26 -0
  128. package/dist/runtime-packages/ui-host-runtime/src/session-ingress-controller.ts +477 -0
  129. package/dist/runtime-packages/ui-host-runtime/src/session-ingress.ts +209 -0
  130. package/dist/runtime-packages/ui-host-runtime/src/session-live-runtime.ts +112 -0
  131. package/dist/runtime-packages/ui-host-runtime/src/session-model.ts +318 -0
  132. package/dist/runtime-packages/ui-host-runtime/src/session-projection.ts +211 -0
  133. package/dist/runtime-packages/ui-host-runtime/src/session-state-reducer.ts +814 -0
  134. package/dist/runtime-packages/ui-host-runtime/src/sse-manager.ts +334 -0
  135. package/dist/runtime-packages/ui-host-runtime/src/unified-session-store.ts +180 -0
  136. package/dist/scaffold/assets/static/app/tsconfig.framework.json +3 -1
  137. package/dist/scaffold/assets/static/ui/tsconfig.framework.json +7 -19
  138. package/package.json +52 -17
  139. package/skills/dreamboard/SKILL.md +41 -75
  140. package/LICENSE +0 -89
  141. package/NOTICE +0 -1
  142. package/dist/chunk-BMYC6772.js.map +0 -1
  143. package/dist/chunk-EYYWGWTO.js.map +0 -1
  144. package/dist/chunk-MOVHYB6E.js.map +0 -1
  145. package/dist/scaffold/assets/static/ui/App.tsx +0 -22
  146. package/dist/src-CUL7EGGG.js +0 -634
  147. package/dist/src-CUL7EGGG.js.map +0 -1
  148. package/skills/dreamboard/references/authoring-lifecycle.md +0 -102
  149. package/skills/dreamboard/references/board-surfaces.md +0 -36
  150. package/skills/dreamboard/references/board-topology.md +0 -443
  151. package/skills/dreamboard/references/boards-and-topology.md +0 -100
  152. package/skills/dreamboard/references/card-actions.md +0 -107
  153. package/skills/dreamboard/references/cli.md +0 -120
  154. package/skills/dreamboard/references/core-concepts.md +0 -514
  155. package/skills/dreamboard/references/custom-renderers.md +0 -26
  156. package/skills/dreamboard/references/derived-values.md +0 -55
  157. package/skills/dreamboard/references/effects.md +0 -111
  158. package/skills/dreamboard/references/game-contract.md +0 -89
  159. package/skills/dreamboard/references/game-definition.md +0 -89
  160. package/skills/dreamboard/references/game-shell.md +0 -80
  161. package/skills/dreamboard/references/hand-surfaces.md +0 -33
  162. package/skills/dreamboard/references/index.md +0 -112
  163. package/skills/dreamboard/references/inputs-and-targets.md +0 -160
  164. package/skills/dreamboard/references/interactions.md +0 -158
  165. package/skills/dreamboard/references/manifest-fields.md +0 -137
  166. package/skills/dreamboard/references/manifest.md +0 -81
  167. package/skills/dreamboard/references/package-surfaces.md +0 -69
  168. package/skills/dreamboard/references/phases.md +0 -145
  169. package/skills/dreamboard/references/prompts-and-choices.md +0 -55
  170. package/skills/dreamboard/references/quickstart.md +0 -71
  171. package/skills/dreamboard/references/rule-authoring.md +0 -144
  172. package/skills/dreamboard/references/setup-bootstrap.md +0 -78
  173. package/skills/dreamboard/references/stages-and-zones.md +0 -59
  174. package/skills/dreamboard/references/static-views.md +0 -67
  175. package/skills/dreamboard/references/table-queries-and-ops.md +0 -103
  176. package/skills/dreamboard/references/testing-bases.md +0 -147
  177. package/skills/dreamboard/references/testing-generated-contracts.md +0 -142
  178. package/skills/dreamboard/references/testing-runtime-assertions.md +0 -124
  179. package/skills/dreamboard/references/testing-scenarios.md +0 -148
  180. package/skills/dreamboard/references/testing-ui-tests.md +0 -174
  181. package/skills/dreamboard/references/testing.md +0 -161
  182. package/skills/dreamboard/references/ui-architecture.md +0 -137
  183. package/skills/dreamboard/references/ui-components.md +0 -34
  184. package/skills/dreamboard/references/views.md +0 -72
  185. package/skills/dreamboard/references/workspace-layout.md +0 -136
  186. /package/dist/{dist-WJRJNFLI.js.map → dist-FRURQI7Q.js.map} +0 -0
@@ -0,0 +1,463 @@
1
+ "use client";
2
+
3
+ import { Button } from "@dreamboard/ui/components/button";
4
+ import {
5
+ ButtonGroup,
6
+ ButtonGroupText,
7
+ } from "@dreamboard/ui/components/button-group";
8
+ import {
9
+ Tooltip,
10
+ TooltipContent,
11
+ TooltipProvider,
12
+ TooltipTrigger,
13
+ } from "@dreamboard/ui/components/tooltip";
14
+ import { cn } from "@dreamboard/ui/lib/utils";
15
+ import type { FileUIPart, UIMessage } from "ai";
16
+ import {
17
+ ChevronLeftIcon,
18
+ ChevronRightIcon,
19
+ PaperclipIcon,
20
+ XIcon,
21
+ } from "lucide-react";
22
+ import type {
23
+ ComponentProps,
24
+ ComponentPropsWithoutRef,
25
+ HTMLAttributes,
26
+ ReactElement,
27
+ } from "react";
28
+ import {
29
+ createContext,
30
+ memo,
31
+ useContext,
32
+ useEffect,
33
+ useMemo,
34
+ useState,
35
+ } from "react";
36
+ import { Streamdown } from "streamdown";
37
+
38
+ export type MessageProps = HTMLAttributes<HTMLDivElement> & {
39
+ from: UIMessage["role"];
40
+ };
41
+
42
+ export const Message = ({ className, from, ...props }: MessageProps) => (
43
+ <div
44
+ className={cn(
45
+ "group flex w-full max-w-[80%] flex-col gap-2",
46
+ from === "user" ? "is-user ml-auto justify-end" : "is-assistant",
47
+ className,
48
+ )}
49
+ {...props}
50
+ />
51
+ );
52
+
53
+ export type MessageContentProps = HTMLAttributes<HTMLDivElement>;
54
+
55
+ export const MessageContent = ({
56
+ children,
57
+ className,
58
+ ...props
59
+ }: MessageContentProps) => (
60
+ <div
61
+ className={cn(
62
+ "flex w-fit flex-col gap-2 overflow-hidden text-sm font-sans",
63
+ "group-[.is-user]:ml-auto group-[.is-user]:bg-[#fff9c4] group-[.is-user]:border-2 group-[.is-user]:border-border group-[.is-user]:wobbly-border-md group-[.is-user]:hard-shadow group-[.is-user]:px-4 group-[.is-user]:py-3 group-[.is-user]:text-foreground",
64
+ "group-[.is-assistant]:bg-white group-[.is-assistant]:border-2 group-[.is-assistant]:border-border group-[.is-assistant]:wobbly-border-md group-[.is-assistant]:hard-shadow group-[.is-assistant]:px-4 group-[.is-assistant]:py-3 group-[.is-assistant]:text-foreground",
65
+ className,
66
+ )}
67
+ {...props}
68
+ >
69
+ {children}
70
+ </div>
71
+ );
72
+
73
+ export type MessageActionsProps = ComponentPropsWithoutRef<"div">;
74
+
75
+ export const MessageActions = ({
76
+ className,
77
+ children,
78
+ ...props
79
+ }: MessageActionsProps) => (
80
+ <div className={cn("flex items-center gap-1", className)} {...props}>
81
+ {children}
82
+ </div>
83
+ );
84
+
85
+ export type MessageActionProps = ComponentProps<typeof Button> & {
86
+ tooltip?: string;
87
+ label?: string;
88
+ };
89
+
90
+ export const MessageAction = ({
91
+ tooltip,
92
+ children,
93
+ label,
94
+ variant = "ghost",
95
+ size = "icon-sm",
96
+ ...props
97
+ }: MessageActionProps) => {
98
+ const button = (
99
+ <Button size={size} type="button" variant={variant} {...props}>
100
+ {children}
101
+ <span className="sr-only">{label || tooltip}</span>
102
+ </Button>
103
+ );
104
+
105
+ if (tooltip) {
106
+ return (
107
+ <TooltipProvider>
108
+ <Tooltip>
109
+ <TooltipTrigger asChild>{button}</TooltipTrigger>
110
+ <TooltipContent>
111
+ <p>{tooltip}</p>
112
+ </TooltipContent>
113
+ </Tooltip>
114
+ </TooltipProvider>
115
+ );
116
+ }
117
+
118
+ return button;
119
+ };
120
+
121
+ interface MessageBranchContextType {
122
+ currentBranch: number;
123
+ totalBranches: number;
124
+ goToPrevious: () => void;
125
+ goToNext: () => void;
126
+ branches: ReactElement[];
127
+ setBranches: (branches: ReactElement[]) => void;
128
+ }
129
+
130
+ const MessageBranchContext = createContext<MessageBranchContextType | null>(
131
+ null,
132
+ );
133
+
134
+ const useMessageBranch = () => {
135
+ const context = useContext(MessageBranchContext);
136
+
137
+ if (!context) {
138
+ throw new Error(
139
+ "MessageBranch components must be used within MessageBranch",
140
+ );
141
+ }
142
+
143
+ return context;
144
+ };
145
+
146
+ export type MessageBranchProps = HTMLAttributes<HTMLDivElement> & {
147
+ defaultBranch?: number;
148
+ onBranchChange?: (branchIndex: number) => void;
149
+ };
150
+
151
+ export const MessageBranch = ({
152
+ defaultBranch = 0,
153
+ onBranchChange,
154
+ className,
155
+ ...props
156
+ }: MessageBranchProps) => {
157
+ const [currentBranch, setCurrentBranch] = useState(defaultBranch);
158
+ const [branches, setBranches] = useState<ReactElement[]>([]);
159
+
160
+ const handleBranchChange = (newBranch: number) => {
161
+ setCurrentBranch(newBranch);
162
+ onBranchChange?.(newBranch);
163
+ };
164
+
165
+ const goToPrevious = () => {
166
+ const newBranch =
167
+ currentBranch > 0 ? currentBranch - 1 : branches.length - 1;
168
+ handleBranchChange(newBranch);
169
+ };
170
+
171
+ const goToNext = () => {
172
+ const newBranch =
173
+ currentBranch < branches.length - 1 ? currentBranch + 1 : 0;
174
+ handleBranchChange(newBranch);
175
+ };
176
+
177
+ const contextValue: MessageBranchContextType = {
178
+ currentBranch,
179
+ totalBranches: branches.length,
180
+ goToPrevious,
181
+ goToNext,
182
+ branches,
183
+ setBranches,
184
+ };
185
+
186
+ return (
187
+ <MessageBranchContext.Provider value={contextValue}>
188
+ <div
189
+ className={cn("grid w-full gap-2 [&>div]:pb-0", className)}
190
+ {...props}
191
+ />
192
+ </MessageBranchContext.Provider>
193
+ );
194
+ };
195
+
196
+ export type MessageBranchContentProps = HTMLAttributes<HTMLDivElement>;
197
+
198
+ export const MessageBranchContent = ({
199
+ children,
200
+ ...props
201
+ }: MessageBranchContentProps) => {
202
+ const { currentBranch, setBranches, branches } = useMessageBranch();
203
+ const childrenArray = useMemo(
204
+ () => (Array.isArray(children) ? children : [children]),
205
+ [children],
206
+ );
207
+
208
+ // Use useEffect to update branches when they change
209
+ useEffect(() => {
210
+ if (branches.length !== childrenArray.length) {
211
+ setBranches(childrenArray);
212
+ }
213
+ }, [childrenArray, branches, setBranches]);
214
+
215
+ return childrenArray.map((branch, index) => (
216
+ <div
217
+ className={cn(
218
+ "grid gap-2 overflow-hidden [&>div]:pb-0",
219
+ index === currentBranch ? "block" : "hidden",
220
+ )}
221
+ key={branch.key}
222
+ {...props}
223
+ >
224
+ {branch}
225
+ </div>
226
+ ));
227
+ };
228
+
229
+ export type MessageBranchSelectorProps = HTMLAttributes<HTMLDivElement> & {
230
+ from: UIMessage["role"];
231
+ };
232
+
233
+ export const MessageBranchSelector = ({
234
+ className: _className,
235
+ from: _from,
236
+ ...props
237
+ }: MessageBranchSelectorProps) => {
238
+ const { totalBranches } = useMessageBranch();
239
+
240
+ // Don't render if there's only one branch
241
+ if (totalBranches <= 1) {
242
+ return null;
243
+ }
244
+
245
+ return (
246
+ <ButtonGroup
247
+ className="[&>*:not(:first-child)]:rounded-l-md [&>*:not(:last-child)]:rounded-r-md"
248
+ orientation="horizontal"
249
+ {...props}
250
+ />
251
+ );
252
+ };
253
+
254
+ export type MessageBranchPreviousProps = ComponentProps<typeof Button>;
255
+
256
+ export const MessageBranchPrevious = ({
257
+ children,
258
+ ...props
259
+ }: MessageBranchPreviousProps) => {
260
+ const { goToPrevious, totalBranches } = useMessageBranch();
261
+
262
+ return (
263
+ <Button
264
+ aria-label="Previous branch"
265
+ disabled={totalBranches <= 1}
266
+ onClick={goToPrevious}
267
+ size="icon-sm"
268
+ type="button"
269
+ variant="ghost"
270
+ {...props}
271
+ >
272
+ {children ?? <ChevronLeftIcon size={14} />}
273
+ </Button>
274
+ );
275
+ };
276
+
277
+ export type MessageBranchNextProps = ComponentProps<typeof Button>;
278
+
279
+ export const MessageBranchNext = ({
280
+ children,
281
+ className: _className,
282
+ ...props
283
+ }: MessageBranchNextProps) => {
284
+ const { goToNext, totalBranches } = useMessageBranch();
285
+
286
+ return (
287
+ <Button
288
+ aria-label="Next branch"
289
+ disabled={totalBranches <= 1}
290
+ onClick={goToNext}
291
+ size="icon-sm"
292
+ type="button"
293
+ variant="ghost"
294
+ {...props}
295
+ >
296
+ {children ?? <ChevronRightIcon size={14} />}
297
+ </Button>
298
+ );
299
+ };
300
+
301
+ export type MessageBranchPageProps = HTMLAttributes<HTMLSpanElement>;
302
+
303
+ export const MessageBranchPage = ({
304
+ className,
305
+ ...props
306
+ }: MessageBranchPageProps) => {
307
+ const { currentBranch, totalBranches } = useMessageBranch();
308
+
309
+ return (
310
+ <ButtonGroupText
311
+ className={cn(
312
+ "border-none bg-transparent text-muted-foreground shadow-none",
313
+ className,
314
+ )}
315
+ {...props}
316
+ >
317
+ {currentBranch + 1} of {totalBranches}
318
+ </ButtonGroupText>
319
+ );
320
+ };
321
+
322
+ export type MessageResponseProps = ComponentProps<typeof Streamdown>;
323
+
324
+ export const MessageResponse = memo(
325
+ ({ className, ...props }: MessageResponseProps) => (
326
+ <Streamdown
327
+ className={cn(
328
+ "size-full [&>*:first-child]:mt-0 [&>*:last-child]:mb-0",
329
+ className,
330
+ )}
331
+ {...props}
332
+ />
333
+ ),
334
+ (prevProps, nextProps) => prevProps.children === nextProps.children,
335
+ );
336
+
337
+ MessageResponse.displayName = "MessageResponse";
338
+
339
+ export type MessageAttachmentProps = HTMLAttributes<HTMLDivElement> & {
340
+ data: FileUIPart;
341
+ className?: string;
342
+ onRemove?: () => void;
343
+ };
344
+
345
+ export function MessageAttachment({
346
+ data,
347
+ className,
348
+ onRemove,
349
+ ...props
350
+ }: MessageAttachmentProps) {
351
+ const filename = data.filename || "";
352
+ const mediaType =
353
+ data.mediaType?.startsWith("image/") && data.url ? "image" : "file";
354
+ const isImage = mediaType === "image";
355
+ const attachmentLabel = filename || (isImage ? "Image" : "Attachment");
356
+
357
+ return (
358
+ <div
359
+ className={cn(
360
+ "group relative size-24 overflow-hidden rounded-lg",
361
+ className,
362
+ )}
363
+ {...props}
364
+ >
365
+ {isImage ? (
366
+ <>
367
+ <img
368
+ alt={filename || "attachment"}
369
+ className="size-full object-cover"
370
+ height={100}
371
+ src={data.url}
372
+ width={100}
373
+ />
374
+ {onRemove && (
375
+ <Button
376
+ aria-label="Remove attachment"
377
+ className="absolute top-2 right-2 size-6 rounded-full bg-background/80 p-0 opacity-0 backdrop-blur-sm transition-opacity hover:bg-background group-hover:opacity-100 [&>svg]:size-3"
378
+ onClick={(e) => {
379
+ e.stopPropagation();
380
+ onRemove();
381
+ }}
382
+ type="button"
383
+ variant="ghost"
384
+ >
385
+ <XIcon />
386
+ <span className="sr-only">Remove</span>
387
+ </Button>
388
+ )}
389
+ </>
390
+ ) : (
391
+ <>
392
+ <Tooltip>
393
+ <TooltipTrigger asChild>
394
+ <div className="flex size-full shrink-0 items-center justify-center rounded-lg bg-muted text-muted-foreground">
395
+ <PaperclipIcon className="size-4" />
396
+ </div>
397
+ </TooltipTrigger>
398
+ <TooltipContent>
399
+ <p>{attachmentLabel}</p>
400
+ </TooltipContent>
401
+ </Tooltip>
402
+ {onRemove && (
403
+ <Button
404
+ aria-label="Remove attachment"
405
+ className="size-6 shrink-0 rounded-full p-0 opacity-0 transition-opacity hover:bg-accent group-hover:opacity-100 [&>svg]:size-3"
406
+ onClick={(e) => {
407
+ e.stopPropagation();
408
+ onRemove();
409
+ }}
410
+ type="button"
411
+ variant="ghost"
412
+ >
413
+ <XIcon />
414
+ <span className="sr-only">Remove</span>
415
+ </Button>
416
+ )}
417
+ </>
418
+ )}
419
+ </div>
420
+ );
421
+ }
422
+
423
+ export type MessageAttachmentsProps = ComponentPropsWithoutRef<"div">;
424
+
425
+ export function MessageAttachments({
426
+ children,
427
+ className,
428
+ ...props
429
+ }: MessageAttachmentsProps) {
430
+ if (!children) {
431
+ return null;
432
+ }
433
+
434
+ return (
435
+ <div
436
+ className={cn(
437
+ "ml-auto flex w-fit flex-wrap items-start gap-2",
438
+ className,
439
+ )}
440
+ {...props}
441
+ >
442
+ {children}
443
+ </div>
444
+ );
445
+ }
446
+
447
+ export type MessageToolbarProps = ComponentPropsWithoutRef<"div">;
448
+
449
+ export const MessageToolbar = ({
450
+ className,
451
+ children,
452
+ ...props
453
+ }: MessageToolbarProps) => (
454
+ <div
455
+ className={cn(
456
+ "mt-4 flex w-full items-center justify-between gap-4",
457
+ className,
458
+ )}
459
+ {...props}
460
+ >
461
+ {children}
462
+ </div>
463
+ );
@@ -0,0 +1,71 @@
1
+ import {
2
+ Card,
3
+ CardAction,
4
+ CardContent,
5
+ CardDescription,
6
+ CardFooter,
7
+ CardHeader,
8
+ CardTitle,
9
+ } from "@dreamboard/ui/components/card";
10
+ import { cn } from "@dreamboard/ui/lib/utils";
11
+ import { Handle, Position } from "@xyflow/react";
12
+ import type { ComponentProps } from "react";
13
+
14
+ export type NodeProps = ComponentProps<typeof Card> & {
15
+ handles: {
16
+ target: boolean;
17
+ source: boolean;
18
+ };
19
+ };
20
+
21
+ export const Node = ({ handles, className, ...props }: NodeProps) => (
22
+ <Card
23
+ className={cn(
24
+ "node-container relative size-full h-auto w-sm gap-0 rounded-md p-0",
25
+ className,
26
+ )}
27
+ {...props}
28
+ >
29
+ {handles.target && <Handle position={Position.Left} type="target" />}
30
+ {handles.source && <Handle position={Position.Right} type="source" />}
31
+ {props.children}
32
+ </Card>
33
+ );
34
+
35
+ export type NodeHeaderProps = ComponentProps<typeof CardHeader>;
36
+
37
+ export const NodeHeader = ({ className, ...props }: NodeHeaderProps) => (
38
+ <CardHeader
39
+ className={cn("gap-0.5 rounded-t-md border-b bg-secondary p-3!", className)}
40
+ {...props}
41
+ />
42
+ );
43
+
44
+ export type NodeTitleProps = ComponentProps<typeof CardTitle>;
45
+
46
+ export const NodeTitle = (props: NodeTitleProps) => <CardTitle {...props} />;
47
+
48
+ export type NodeDescriptionProps = ComponentProps<typeof CardDescription>;
49
+
50
+ export const NodeDescription = (props: NodeDescriptionProps) => (
51
+ <CardDescription {...props} />
52
+ );
53
+
54
+ export type NodeActionProps = ComponentProps<typeof CardAction>;
55
+
56
+ export const NodeAction = (props: NodeActionProps) => <CardAction {...props} />;
57
+
58
+ export type NodeContentProps = ComponentProps<typeof CardContent>;
59
+
60
+ export const NodeContent = ({ className, ...props }: NodeContentProps) => (
61
+ <CardContent className={cn("p-3", className)} {...props} />
62
+ );
63
+
64
+ export type NodeFooterProps = ComponentProps<typeof CardFooter>;
65
+
66
+ export const NodeFooter = ({ className, ...props }: NodeFooterProps) => (
67
+ <CardFooter
68
+ className={cn("rounded-b-md border-t bg-secondary p-3!", className)}
69
+ {...props}
70
+ />
71
+ );