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,228 @@
1
+ "use client";
2
+
3
+ import { useControllableState } from "@radix-ui/react-use-controllable-state";
4
+ import { Badge } from "@dreamboard/ui/components/badge";
5
+ import {
6
+ Collapsible,
7
+ CollapsibleContent,
8
+ CollapsibleTrigger,
9
+ } from "@dreamboard/ui/components/collapsible";
10
+ import { cn } from "@dreamboard/ui/lib/utils";
11
+ import {
12
+ BrainIcon,
13
+ ChevronDownIcon,
14
+ DotIcon,
15
+ type LucideIcon,
16
+ } from "lucide-react";
17
+ import type { ComponentProps, ReactNode } from "react";
18
+ import { createContext, memo, useContext, useMemo } from "react";
19
+
20
+ interface ChainOfThoughtContextValue {
21
+ isOpen: boolean;
22
+ setIsOpen: (open: boolean) => void;
23
+ }
24
+
25
+ const ChainOfThoughtContext = createContext<ChainOfThoughtContextValue | null>(
26
+ null,
27
+ );
28
+
29
+ const useChainOfThought = () => {
30
+ const context = useContext(ChainOfThoughtContext);
31
+ if (!context) {
32
+ throw new Error(
33
+ "ChainOfThought components must be used within ChainOfThought",
34
+ );
35
+ }
36
+ return context;
37
+ };
38
+
39
+ export type ChainOfThoughtProps = ComponentProps<"div"> & {
40
+ open?: boolean;
41
+ defaultOpen?: boolean;
42
+ onOpenChange?: (open: boolean) => void;
43
+ };
44
+
45
+ export const ChainOfThought = memo(
46
+ ({
47
+ className,
48
+ open,
49
+ defaultOpen = false,
50
+ onOpenChange,
51
+ children,
52
+ ...props
53
+ }: ChainOfThoughtProps) => {
54
+ const [isOpen, setIsOpen] = useControllableState({
55
+ prop: open,
56
+ defaultProp: defaultOpen,
57
+ onChange: onOpenChange,
58
+ });
59
+
60
+ const chainOfThoughtContext = useMemo(
61
+ () => ({ isOpen, setIsOpen }),
62
+ [isOpen, setIsOpen],
63
+ );
64
+
65
+ return (
66
+ <ChainOfThoughtContext.Provider value={chainOfThoughtContext}>
67
+ <div
68
+ className={cn("not-prose max-w-prose space-y-4", className)}
69
+ {...props}
70
+ >
71
+ {children}
72
+ </div>
73
+ </ChainOfThoughtContext.Provider>
74
+ );
75
+ },
76
+ );
77
+
78
+ export type ChainOfThoughtHeaderProps = ComponentProps<
79
+ typeof CollapsibleTrigger
80
+ >;
81
+
82
+ export const ChainOfThoughtHeader = memo(
83
+ ({ className, children, ...props }: ChainOfThoughtHeaderProps) => {
84
+ const { isOpen, setIsOpen } = useChainOfThought();
85
+
86
+ return (
87
+ <Collapsible onOpenChange={setIsOpen} open={isOpen}>
88
+ <CollapsibleTrigger
89
+ className={cn(
90
+ "flex w-full items-center gap-2 text-muted-foreground text-sm transition-colors hover:text-foreground",
91
+ className,
92
+ )}
93
+ {...props}
94
+ >
95
+ <BrainIcon className="size-4" />
96
+ <span className="flex-1 text-left">
97
+ {children ?? "Chain of Thought"}
98
+ </span>
99
+ <ChevronDownIcon
100
+ className={cn(
101
+ "size-4 transition-transform",
102
+ isOpen ? "rotate-180" : "rotate-0",
103
+ )}
104
+ />
105
+ </CollapsibleTrigger>
106
+ </Collapsible>
107
+ );
108
+ },
109
+ );
110
+
111
+ export type ChainOfThoughtStepProps = ComponentProps<"div"> & {
112
+ icon?: LucideIcon;
113
+ label: ReactNode;
114
+ description?: ReactNode;
115
+ status?: "complete" | "active" | "pending";
116
+ };
117
+
118
+ export const ChainOfThoughtStep = memo(
119
+ ({
120
+ className,
121
+ icon: Icon = DotIcon,
122
+ label,
123
+ description,
124
+ status = "complete",
125
+ children,
126
+ ...props
127
+ }: ChainOfThoughtStepProps) => {
128
+ const statusStyles = {
129
+ complete: "text-muted-foreground",
130
+ active: "text-foreground",
131
+ pending: "text-muted-foreground/50",
132
+ };
133
+
134
+ return (
135
+ <div
136
+ className={cn(
137
+ "flex gap-2 text-sm",
138
+ statusStyles[status],
139
+ "fade-in-0 slide-in-from-top-2 animate-in",
140
+ className,
141
+ )}
142
+ {...props}
143
+ >
144
+ <div className="relative mt-0.5">
145
+ <Icon className="size-4" />
146
+ <div className="-mx-px absolute top-7 bottom-0 left-1/2 w-px bg-border" />
147
+ </div>
148
+ <div className="flex-1 space-y-2">
149
+ <div>{label}</div>
150
+ {description && (
151
+ <div className="text-muted-foreground text-xs">{description}</div>
152
+ )}
153
+ {children}
154
+ </div>
155
+ </div>
156
+ );
157
+ },
158
+ );
159
+
160
+ export type ChainOfThoughtSearchResultsProps = ComponentProps<"div">;
161
+
162
+ export const ChainOfThoughtSearchResults = memo(
163
+ ({ className, ...props }: ChainOfThoughtSearchResultsProps) => (
164
+ <div className={cn("flex items-center gap-2", className)} {...props} />
165
+ ),
166
+ );
167
+
168
+ export type ChainOfThoughtSearchResultProps = ComponentProps<typeof Badge>;
169
+
170
+ export const ChainOfThoughtSearchResult = memo(
171
+ ({ className, children, ...props }: ChainOfThoughtSearchResultProps) => (
172
+ <Badge
173
+ className={cn("gap-1 px-2 py-0.5 font-normal text-xs", className)}
174
+ variant="secondary"
175
+ {...props}
176
+ >
177
+ {children}
178
+ </Badge>
179
+ ),
180
+ );
181
+
182
+ export type ChainOfThoughtContentProps = ComponentProps<
183
+ typeof CollapsibleContent
184
+ >;
185
+
186
+ export const ChainOfThoughtContent = memo(
187
+ ({ className, children, ...props }: ChainOfThoughtContentProps) => {
188
+ const { isOpen } = useChainOfThought();
189
+
190
+ return (
191
+ <Collapsible open={isOpen}>
192
+ <CollapsibleContent
193
+ className={cn(
194
+ "mt-2 space-y-3",
195
+ "data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 text-popover-foreground outline-none data-[state=closed]:animate-out data-[state=open]:animate-in",
196
+ className,
197
+ )}
198
+ {...props}
199
+ >
200
+ {children}
201
+ </CollapsibleContent>
202
+ </Collapsible>
203
+ );
204
+ },
205
+ );
206
+
207
+ export type ChainOfThoughtImageProps = ComponentProps<"div"> & {
208
+ caption?: string;
209
+ };
210
+
211
+ export const ChainOfThoughtImage = memo(
212
+ ({ className, children, caption, ...props }: ChainOfThoughtImageProps) => (
213
+ <div className={cn("mt-2 space-y-2", className)} {...props}>
214
+ <div className="relative flex max-h-[22rem] items-center justify-center overflow-hidden rounded-lg bg-muted p-3">
215
+ {children}
216
+ </div>
217
+ {caption && <p className="text-muted-foreground text-xs">{caption}</p>}
218
+ </div>
219
+ ),
220
+ );
221
+
222
+ ChainOfThought.displayName = "ChainOfThought";
223
+ ChainOfThoughtHeader.displayName = "ChainOfThoughtHeader";
224
+ ChainOfThoughtStep.displayName = "ChainOfThoughtStep";
225
+ ChainOfThoughtSearchResults.displayName = "ChainOfThoughtSearchResults";
226
+ ChainOfThoughtSearchResult.displayName = "ChainOfThoughtSearchResult";
227
+ ChainOfThoughtContent.displayName = "ChainOfThoughtContent";
228
+ ChainOfThoughtImage.displayName = "ChainOfThoughtImage";
@@ -0,0 +1,179 @@
1
+ "use client";
2
+
3
+ import { Button } from "@dreamboard/ui/components/button";
4
+ import { cn } from "@dreamboard/ui/lib/utils";
5
+ import type { Element } from "hast";
6
+ import { CheckIcon, CopyIcon } from "lucide-react";
7
+ import {
8
+ type ComponentProps,
9
+ createContext,
10
+ type HTMLAttributes,
11
+ useContext,
12
+ useEffect,
13
+ useRef,
14
+ useState,
15
+ } from "react";
16
+ import { type BundledLanguage, codeToHtml, type ShikiTransformer } from "shiki";
17
+
18
+ type CodeBlockProps = HTMLAttributes<HTMLDivElement> & {
19
+ code: string;
20
+ language: BundledLanguage;
21
+ showLineNumbers?: boolean;
22
+ };
23
+
24
+ interface CodeBlockContextType {
25
+ code: string;
26
+ }
27
+
28
+ const CodeBlockContext = createContext<CodeBlockContextType>({
29
+ code: "",
30
+ });
31
+
32
+ const lineNumberTransformer: ShikiTransformer = {
33
+ name: "line-numbers",
34
+ line(node: Element, line: number) {
35
+ node.children.unshift({
36
+ type: "element",
37
+ tagName: "span",
38
+ properties: {
39
+ className: [
40
+ "inline-block",
41
+ "min-w-10",
42
+ "mr-4",
43
+ "text-right",
44
+ "select-none",
45
+ "text-muted-foreground",
46
+ ],
47
+ },
48
+ children: [{ type: "text", value: String(line) }],
49
+ });
50
+ },
51
+ };
52
+
53
+ export async function highlightCode(
54
+ code: string,
55
+ language: BundledLanguage,
56
+ showLineNumbers = false,
57
+ ) {
58
+ const transformers: ShikiTransformer[] = showLineNumbers
59
+ ? [lineNumberTransformer]
60
+ : [];
61
+
62
+ return await Promise.all([
63
+ codeToHtml(code, {
64
+ lang: language,
65
+ theme: "one-light",
66
+ transformers,
67
+ }),
68
+ codeToHtml(code, {
69
+ lang: language,
70
+ theme: "one-dark-pro",
71
+ transformers,
72
+ }),
73
+ ]);
74
+ }
75
+
76
+ export const CodeBlock = ({
77
+ code,
78
+ language,
79
+ showLineNumbers = false,
80
+ className,
81
+ children,
82
+ ...props
83
+ }: CodeBlockProps) => {
84
+ const [html, setHtml] = useState<string>("");
85
+ const [darkHtml, setDarkHtml] = useState<string>("");
86
+ const mounted = useRef(false);
87
+
88
+ useEffect(() => {
89
+ highlightCode(code, language, showLineNumbers).then(([light, dark]) => {
90
+ if (!mounted.current) {
91
+ setHtml(light);
92
+ setDarkHtml(dark);
93
+ mounted.current = true;
94
+ }
95
+ });
96
+
97
+ return () => {
98
+ mounted.current = false;
99
+ };
100
+ }, [code, language, showLineNumbers]);
101
+
102
+ return (
103
+ <CodeBlockContext.Provider value={{ code }}>
104
+ <div
105
+ className={cn(
106
+ "group relative w-full overflow-hidden rounded-md border bg-background text-foreground",
107
+ className,
108
+ )}
109
+ {...props}
110
+ >
111
+ <div className="relative">
112
+ <div
113
+ className="overflow-hidden dark:hidden [&>pre]:m-0 [&>pre]:bg-background! [&>pre]:p-4 [&>pre]:text-foreground! [&>pre]:text-sm [&_code]:font-mono [&_code]:text-sm"
114
+ // biome-ignore lint/security/noDangerouslySetInnerHtml: "this is needed."
115
+ dangerouslySetInnerHTML={{ __html: html }}
116
+ />
117
+ <div
118
+ className="hidden overflow-hidden dark:block [&>pre]:m-0 [&>pre]:bg-background! [&>pre]:p-4 [&>pre]:text-foreground! [&>pre]:text-sm [&_code]:font-mono [&_code]:text-sm"
119
+ // biome-ignore lint/security/noDangerouslySetInnerHtml: "this is needed."
120
+ dangerouslySetInnerHTML={{ __html: darkHtml }}
121
+ />
122
+ {children && (
123
+ <div className="absolute top-2 right-2 flex items-center gap-2">
124
+ {children}
125
+ </div>
126
+ )}
127
+ </div>
128
+ </div>
129
+ </CodeBlockContext.Provider>
130
+ );
131
+ };
132
+
133
+ export type CodeBlockCopyButtonProps = ComponentProps<typeof Button> & {
134
+ onCopy?: () => void;
135
+ onError?: (error: Error) => void;
136
+ timeout?: number;
137
+ };
138
+
139
+ export const CodeBlockCopyButton = ({
140
+ onCopy,
141
+ onError,
142
+ timeout = 2000,
143
+ children,
144
+ className,
145
+ ...props
146
+ }: CodeBlockCopyButtonProps) => {
147
+ const [isCopied, setIsCopied] = useState(false);
148
+ const { code } = useContext(CodeBlockContext);
149
+
150
+ const copyToClipboard = async () => {
151
+ if (typeof window === "undefined" || !navigator?.clipboard?.writeText) {
152
+ onError?.(new Error("Clipboard API not available"));
153
+ return;
154
+ }
155
+
156
+ try {
157
+ await navigator.clipboard.writeText(code);
158
+ setIsCopied(true);
159
+ onCopy?.();
160
+ setTimeout(() => setIsCopied(false), timeout);
161
+ } catch (error) {
162
+ onError?.(error as Error);
163
+ }
164
+ };
165
+
166
+ const Icon = isCopied ? CheckIcon : CopyIcon;
167
+
168
+ return (
169
+ <Button
170
+ className={cn("shrink-0", className)}
171
+ onClick={copyToClipboard}
172
+ size="icon"
173
+ variant="ghost"
174
+ {...props}
175
+ >
176
+ {children ?? <Icon size={14} />}
177
+ </Button>
178
+ );
179
+ };
@@ -0,0 +1,158 @@
1
+ "use client";
2
+
3
+ import { Alert, AlertDescription } from "@dreamboard/ui/components/alert";
4
+ import { Button } from "@dreamboard/ui/components/button";
5
+ import { cn } from "@dreamboard/ui/lib/utils";
6
+ import type { ToolUIPart } from "ai";
7
+ import {
8
+ type ComponentProps,
9
+ createContext,
10
+ type ReactNode,
11
+ useContext,
12
+ } from "react";
13
+
14
+ interface ConfirmationApproval {
15
+ approved?: boolean;
16
+ }
17
+
18
+ type ConfirmationState =
19
+ | ToolUIPart["state"]
20
+ | "approval-requested"
21
+ | "approval-responded"
22
+ | "output-denied";
23
+
24
+ interface ConfirmationContextValue {
25
+ approval?: ConfirmationApproval;
26
+ state: ConfirmationState;
27
+ }
28
+
29
+ const ConfirmationContext = createContext<ConfirmationContextValue | null>(
30
+ null,
31
+ );
32
+
33
+ const useConfirmation = () => {
34
+ const context = useContext(ConfirmationContext);
35
+
36
+ if (!context) {
37
+ throw new Error("Confirmation components must be used within Confirmation");
38
+ }
39
+
40
+ return context;
41
+ };
42
+
43
+ export type ConfirmationProps = ComponentProps<typeof Alert> & {
44
+ approval?: ConfirmationApproval;
45
+ state: ConfirmationState;
46
+ };
47
+
48
+ export const Confirmation = ({
49
+ className,
50
+ approval,
51
+ state,
52
+ ...props
53
+ }: ConfirmationProps) => {
54
+ if (!approval || state === "input-streaming" || state === "input-available") {
55
+ return null;
56
+ }
57
+
58
+ return (
59
+ <ConfirmationContext.Provider value={{ approval, state }}>
60
+ <Alert className={cn("flex flex-col gap-2", className)} {...props} />
61
+ </ConfirmationContext.Provider>
62
+ );
63
+ };
64
+
65
+ export type ConfirmationTitleProps = ComponentProps<typeof AlertDescription>;
66
+
67
+ export const ConfirmationTitle = ({
68
+ className,
69
+ ...props
70
+ }: ConfirmationTitleProps) => (
71
+ <AlertDescription className={cn("inline", className)} {...props} />
72
+ );
73
+
74
+ export interface ConfirmationRequestProps {
75
+ children?: ReactNode;
76
+ }
77
+
78
+ export const ConfirmationRequest = ({ children }: ConfirmationRequestProps) => {
79
+ const { state } = useConfirmation();
80
+
81
+ // Only show when approval is requested
82
+ if (state !== "approval-requested") {
83
+ return null;
84
+ }
85
+
86
+ return children;
87
+ };
88
+
89
+ export interface ConfirmationAcceptedProps {
90
+ children?: ReactNode;
91
+ }
92
+
93
+ export const ConfirmationAccepted = ({
94
+ children,
95
+ }: ConfirmationAcceptedProps) => {
96
+ const { approval, state } = useConfirmation();
97
+
98
+ // Only show when approved and in response states
99
+ if (
100
+ !approval?.approved ||
101
+ (state !== "approval-responded" &&
102
+ state !== "output-denied" &&
103
+ state !== "output-available")
104
+ ) {
105
+ return null;
106
+ }
107
+
108
+ return children;
109
+ };
110
+
111
+ export interface ConfirmationRejectedProps {
112
+ children?: ReactNode;
113
+ }
114
+
115
+ export const ConfirmationRejected = ({
116
+ children,
117
+ }: ConfirmationRejectedProps) => {
118
+ const { approval, state } = useConfirmation();
119
+
120
+ // Only show when rejected and in response states
121
+ if (
122
+ approval?.approved !== false ||
123
+ (state !== "approval-responded" &&
124
+ state !== "output-denied" &&
125
+ state !== "output-available")
126
+ ) {
127
+ return null;
128
+ }
129
+
130
+ return children;
131
+ };
132
+
133
+ export type ConfirmationActionsProps = ComponentProps<"div">;
134
+
135
+ export const ConfirmationActions = ({
136
+ className,
137
+ ...props
138
+ }: ConfirmationActionsProps) => {
139
+ const { state } = useConfirmation();
140
+
141
+ // Only show when approval is requested
142
+ if (state !== "approval-requested") {
143
+ return null;
144
+ }
145
+
146
+ return (
147
+ <div
148
+ className={cn("flex items-center justify-end gap-2 self-end", className)}
149
+ {...props}
150
+ />
151
+ );
152
+ };
153
+
154
+ export type ConfirmationActionProps = ComponentProps<typeof Button>;
155
+
156
+ export const ConfirmationAction = (props: ConfirmationActionProps) => (
157
+ <Button className="h-8 px-3 text-sm" type="button" {...props} />
158
+ );
@@ -0,0 +1,28 @@
1
+ import type { ConnectionLineComponent } from "@xyflow/react";
2
+
3
+ const HALF = 0.5;
4
+
5
+ export const Connection: ConnectionLineComponent = ({
6
+ fromX,
7
+ fromY,
8
+ toX,
9
+ toY,
10
+ }) => (
11
+ <g>
12
+ <path
13
+ className="animated"
14
+ d={`M${fromX},${fromY} C ${fromX + (toX - fromX) * HALF},${fromY} ${fromX + (toX - fromX) * HALF},${toY} ${toX},${toY}`}
15
+ fill="none"
16
+ stroke="var(--color-ring)"
17
+ strokeWidth={1}
18
+ />
19
+ <circle
20
+ cx={toX}
21
+ cy={toY}
22
+ fill="#fff"
23
+ r={3}
24
+ stroke="var(--color-ring)"
25
+ strokeWidth={1}
26
+ />
27
+ </g>
28
+ );