ai-design-system 0.1.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 (290) hide show
  1. package/README.md +307 -0
  2. package/components/ai-elements/actions.tsx +65 -0
  3. package/components/ai-elements/artifact.tsx +147 -0
  4. package/components/ai-elements/branch.tsx +212 -0
  5. package/components/ai-elements/canvas.tsx +24 -0
  6. package/components/ai-elements/chain-of-thought.tsx +228 -0
  7. package/components/ai-elements/code-block.tsx +179 -0
  8. package/components/ai-elements/confirmation.tsx +169 -0
  9. package/components/ai-elements/connection.tsx +28 -0
  10. package/components/ai-elements/context.tsx +408 -0
  11. package/components/ai-elements/controls.tsx +18 -0
  12. package/components/ai-elements/conversation.tsx +97 -0
  13. package/components/ai-elements/edge.tsx +140 -0
  14. package/components/ai-elements/image.tsx +24 -0
  15. package/components/ai-elements/inline-citation.tsx +287 -0
  16. package/components/ai-elements/loader.tsx +96 -0
  17. package/components/ai-elements/message.tsx +80 -0
  18. package/components/ai-elements/node.tsx +71 -0
  19. package/components/ai-elements/open-in-chat.tsx +363 -0
  20. package/components/ai-elements/panel.tsx +15 -0
  21. package/components/ai-elements/plan.tsx +142 -0
  22. package/components/ai-elements/prompt-input.tsx +1352 -0
  23. package/components/ai-elements/queue.tsx +274 -0
  24. package/components/ai-elements/reasoning.tsx +178 -0
  25. package/components/ai-elements/response.tsx +22 -0
  26. package/components/ai-elements/shimmer.tsx +64 -0
  27. package/components/ai-elements/sources.tsx +77 -0
  28. package/components/ai-elements/suggestion.tsx +56 -0
  29. package/components/ai-elements/task.tsx +87 -0
  30. package/components/ai-elements/tool.tsx +179 -0
  31. package/components/ai-elements/toolbar.tsx +16 -0
  32. package/components/ai-elements/web-preview.tsx +263 -0
  33. package/components/blocks/AIConversation/AIConversation.stories.tsx +164 -0
  34. package/components/blocks/AIConversation/AIConversation.tsx +186 -0
  35. package/components/blocks/AIConversation/index.ts +8 -0
  36. package/components/blocks/AppSidebar/AppSidebar.stories.tsx +63 -0
  37. package/components/blocks/AppSidebar/AppSidebar.tsx +87 -0
  38. package/components/blocks/AppSidebar/index.ts +2 -0
  39. package/components/blocks/DocumentEditorWithComments/DocumentEditorWithComments.stories.tsx +341 -0
  40. package/components/blocks/DocumentEditorWithComments/DocumentEditorWithComments.tsx +255 -0
  41. package/components/blocks/DocumentEditorWithComments/index.ts +9 -0
  42. package/components/blocks/FileChangeQueue/FileChangeQueue.stories.tsx +207 -0
  43. package/components/blocks/FileChangeQueue/FileChangeQueue.tsx +143 -0
  44. package/components/blocks/FileChangeQueue/index.ts +7 -0
  45. package/components/blocks/LayoutProvider/LayoutProvider.tsx +34 -0
  46. package/components/blocks/LayoutProvider/index.ts +1 -0
  47. package/components/blocks/index.ts +2 -0
  48. package/components/composites/AgentIndicator/AgentIndicator.stories.tsx +154 -0
  49. package/components/composites/AgentIndicator/AgentIndicator.tsx +102 -0
  50. package/components/composites/AgentIndicator/index.ts +8 -0
  51. package/components/composites/AppHeader/AppHeader.stories.tsx +46 -0
  52. package/components/composites/AppHeader/AppHeader.tsx +24 -0
  53. package/components/composites/AppHeader/index.ts +2 -0
  54. package/components/composites/CommentBox/CommentBox.stories.tsx +192 -0
  55. package/components/composites/CommentBox/CommentBox.tsx +364 -0
  56. package/components/composites/CommentBox/index.ts +8 -0
  57. package/components/composites/Confirmation/Confirmation.stories.tsx +151 -0
  58. package/components/composites/Confirmation/Confirmation.tsx +93 -0
  59. package/components/composites/Confirmation/index.ts +7 -0
  60. package/components/composites/DataTable/DataTable.stories.tsx +35 -0
  61. package/components/composites/DataTable/DataTable.tsx +95 -0
  62. package/components/composites/DataTable/index.ts +2 -0
  63. package/components/composites/DocumentEditor/DocumentEditor.css +106 -0
  64. package/components/composites/DocumentEditor/DocumentEditor.stories.tsx +927 -0
  65. package/components/composites/DocumentEditor/DocumentEditor.tsx +279 -0
  66. package/components/composites/DocumentEditor/index.ts +8 -0
  67. package/components/composites/FileQueue/FileQueue.stories.tsx +175 -0
  68. package/components/composites/FileQueue/FileQueue.tsx +161 -0
  69. package/components/composites/FileQueue/FileStatusBadge.tsx +74 -0
  70. package/components/composites/FileQueue/index.ts +24 -0
  71. package/components/composites/InteractiveChart/InteractiveChart.stories.tsx +49 -0
  72. package/components/composites/InteractiveChart/InteractiveChart.tsx +69 -0
  73. package/components/composites/InteractiveChart/index.ts +2 -0
  74. package/components/composites/ModeToggle/ModeToggle.stories.tsx +212 -0
  75. package/components/composites/ModeToggle/ModeToggle.tsx +100 -0
  76. package/components/composites/ModeToggle/index.ts +7 -0
  77. package/components/composites/NavUser/NavUser.stories.tsx +50 -0
  78. package/components/composites/NavUser/NavUser.tsx +60 -0
  79. package/components/composites/NavUser/index.ts +2 -0
  80. package/components/composites/NavigationList/NavigationList.stories.tsx +46 -0
  81. package/components/composites/NavigationList/NavigationList.tsx +46 -0
  82. package/components/composites/NavigationList/index.ts +2 -0
  83. package/components/composites/OrchestratorMessage/OrchestratorMessage.stories.tsx +188 -0
  84. package/components/composites/OrchestratorMessage/OrchestratorMessage.tsx +72 -0
  85. package/components/composites/OrchestratorMessage/index.ts +8 -0
  86. package/components/composites/PageContainer/PageContainer.stories.tsx +41 -0
  87. package/components/composites/PageContainer/PageContainer.tsx +24 -0
  88. package/components/composites/PageContainer/index.ts +2 -0
  89. package/components/composites/PromptInput/PromptInput.stories.tsx +200 -0
  90. package/components/composites/PromptInput/PromptInput.tsx +129 -0
  91. package/components/composites/PromptInput/index.ts +8 -0
  92. package/components/composites/SpecialistMessage/SpecialistMessage.stories.tsx +286 -0
  93. package/components/composites/SpecialistMessage/SpecialistMessage.tsx +107 -0
  94. package/components/composites/SpecialistMessage/index.ts +8 -0
  95. package/components/composites/StatsCard/StatsCard.stories.tsx +76 -0
  96. package/components/composites/StatsCard/StatsCard.tsx +81 -0
  97. package/components/composites/StatsCard/index.ts +2 -0
  98. package/components/composites/TablePagination/TablePagination.stories.tsx +38 -0
  99. package/components/composites/TablePagination/TablePagination.tsx +119 -0
  100. package/components/composites/TablePagination/index.ts +2 -0
  101. package/components/composites/TableToolbar/TableToolbar.stories.tsx +60 -0
  102. package/components/composites/TableToolbar/TableToolbar.tsx +66 -0
  103. package/components/composites/TableToolbar/index.ts +2 -0
  104. package/components/composites/ThemeSelector/ThemeSelector.stories.tsx +48 -0
  105. package/components/composites/ThemeSelector/ThemeSelector.tsx +79 -0
  106. package/components/composites/ThemeSelector/index.ts +2 -0
  107. package/components/composites/ToolCallDisplay/ToolCallDisplay.stories.tsx +49 -0
  108. package/components/composites/ToolCallDisplay/ToolCallDisplay.tsx +108 -0
  109. package/components/composites/ToolCallDisplay/index.ts +8 -0
  110. package/components/composites/UserMessage/UserMessage.stories.tsx +59 -0
  111. package/components/composites/UserMessage/UserMessage.tsx +52 -0
  112. package/components/composites/UserMessage/index.ts +8 -0
  113. package/components/composites/index.ts +90 -0
  114. package/components/features/AIDocEditor/AIDocEditor.behaviors.stories.tsx +451 -0
  115. package/components/features/AIDocEditor/AIDocEditor.mocks.ts +96 -0
  116. package/components/features/AIDocEditor/AIDocEditor.stories.tsx +140 -0
  117. package/components/features/AIDocEditor/AIDocEditor.tsx +130 -0
  118. package/components/features/AIDocEditor/index.ts +8 -0
  119. package/components/features/AIDocEditor/useAIDocEditor.d.ts +97 -0
  120. package/components/features/AIDocEditor/useAIDocEditor.mock.ts +83 -0
  121. package/components/features/PageLayout/PageLayout.behaviors.stories.tsx +119 -0
  122. package/components/features/PageLayout/PageLayout.mocks.ts +27 -0
  123. package/components/features/PageLayout/PageLayout.stories.tsx +142 -0
  124. package/components/features/PageLayout/PageLayout.tsx +94 -0
  125. package/components/features/PageLayout/index.ts +4 -0
  126. package/components/features/PageLayout/usePageLayout.d.ts +24 -0
  127. package/components/features/PageLayout/usePageLayout.mock.ts +19 -0
  128. package/components/features/RefinementPanel/README.md +189 -0
  129. package/components/features/RefinementPanel/RefinementPanel.behaviors.stories.tsx +475 -0
  130. package/components/features/RefinementPanel/RefinementPanel.mocks.ts +131 -0
  131. package/components/features/RefinementPanel/RefinementPanel.stories.tsx +141 -0
  132. package/components/features/RefinementPanel/RefinementPanel.tsx +160 -0
  133. package/components/features/RefinementPanel/index.ts +25 -0
  134. package/components/features/RefinementPanel/useRefinementPanel.d.ts +74 -0
  135. package/components/features/RefinementPanel/useRefinementPanel.mock.ts +121 -0
  136. package/components/features/SpecNavigator/SpecNavigator.behaviors.stories.tsx +379 -0
  137. package/components/features/SpecNavigator/SpecNavigator.mocks.ts +131 -0
  138. package/components/features/SpecNavigator/SpecNavigator.stories.tsx +122 -0
  139. package/components/features/SpecNavigator/SpecNavigator.tsx +43 -0
  140. package/components/features/SpecNavigator/index.ts +2 -0
  141. package/components/features/SpecNavigator/useSpecNavigator.d.ts +122 -0
  142. package/components/features/SpecNavigator/useSpecNavigator.mock.ts +93 -0
  143. package/components/features/index.ts +18 -0
  144. package/components/index.ts +14 -0
  145. package/components/primitives/Accordion/Accordion.stories.tsx +87 -0
  146. package/components/primitives/Accordion/Accordion.tsx +66 -0
  147. package/components/primitives/Accordion/index.ts +13 -0
  148. package/components/primitives/Alert/Alert.stories.tsx +422 -0
  149. package/components/primitives/Alert/Alert.tsx +61 -0
  150. package/components/primitives/Alert/index.ts +8 -0
  151. package/components/primitives/AlertDialog/AlertDialog.stories.tsx +367 -0
  152. package/components/primitives/AlertDialog/AlertDialog.tsx +182 -0
  153. package/components/primitives/AlertDialog/index.ts +25 -0
  154. package/components/primitives/Avatar/Avatar.stories.tsx +321 -0
  155. package/components/primitives/Avatar/Avatar.tsx +63 -0
  156. package/components/primitives/Avatar/index.ts +8 -0
  157. package/components/primitives/Badge/Badge.stories.tsx +74 -0
  158. package/components/primitives/Badge/Badge.tsx +49 -0
  159. package/components/primitives/Badge/index.ts +2 -0
  160. package/components/primitives/Button/Button.stories.tsx +445 -0
  161. package/components/primitives/Button/Button.tsx +89 -0
  162. package/components/primitives/Button/index.ts +7 -0
  163. package/components/primitives/Card/Card.stories.tsx +831 -0
  164. package/components/primitives/Card/Card.tsx +242 -0
  165. package/components/primitives/Card/index.ts +30 -0
  166. package/components/primitives/Carousel/Carousel.stories.tsx +32 -0
  167. package/components/primitives/Carousel/Carousel.tsx +63 -0
  168. package/components/primitives/Carousel/index.ts +13 -0
  169. package/components/primitives/Chart/Chart.stories.tsx +346 -0
  170. package/components/primitives/Chart/Chart.tsx +117 -0
  171. package/components/primitives/Chart/index.ts +20 -0
  172. package/components/primitives/Checkbox/Checkbox.stories.tsx +87 -0
  173. package/components/primitives/Checkbox/Checkbox.tsx +38 -0
  174. package/components/primitives/Checkbox/index.ts +2 -0
  175. package/components/primitives/Collapsible/Collapsible.stories.tsx +38 -0
  176. package/components/primitives/Collapsible/Collapsible.tsx +39 -0
  177. package/components/primitives/Collapsible/index.ts +8 -0
  178. package/components/primitives/Command/Command.stories.tsx +150 -0
  179. package/components/primitives/Command/Command.tsx +147 -0
  180. package/components/primitives/Command/index.ts +20 -0
  181. package/components/primitives/Dialog/Dialog.stories.tsx +390 -0
  182. package/components/primitives/Dialog/Dialog.tsx +140 -0
  183. package/components/primitives/Dialog/index.ts +22 -0
  184. package/components/primitives/Drawer/Drawer.stories.tsx +327 -0
  185. package/components/primitives/Drawer/Drawer.tsx +208 -0
  186. package/components/primitives/Drawer/index.ts +27 -0
  187. package/components/primitives/DropdownMenu/DropdownMenu.stories.tsx +150 -0
  188. package/components/primitives/DropdownMenu/DropdownMenu.tsx +73 -0
  189. package/components/primitives/DropdownMenu/index.ts +1 -0
  190. package/components/primitives/HoverCard/HoverCard.stories.tsx +26 -0
  191. package/components/primitives/HoverCard/HoverCard.tsx +39 -0
  192. package/components/primitives/HoverCard/index.ts +8 -0
  193. package/components/primitives/Icon/Icon.stories.tsx +281 -0
  194. package/components/primitives/Icon/Icon.tsx +87 -0
  195. package/components/primitives/Icon/index.ts +8 -0
  196. package/components/primitives/Input/Input.stories.tsx +370 -0
  197. package/components/primitives/Input/Input.tsx +88 -0
  198. package/components/primitives/Input/index.ts +7 -0
  199. package/components/primitives/InputGroup/InputGroup.stories.tsx +40 -0
  200. package/components/primitives/InputGroup/InputGroup.tsx +72 -0
  201. package/components/primitives/InputGroup/index.ts +14 -0
  202. package/components/primitives/Label/Label.stories.tsx +227 -0
  203. package/components/primitives/Label/Label.tsx +53 -0
  204. package/components/primitives/Label/index.ts +7 -0
  205. package/components/primitives/Popover/Popover.stories.tsx +42 -0
  206. package/components/primitives/Popover/Popover.tsx +107 -0
  207. package/components/primitives/Popover/index.ts +2 -0
  208. package/components/primitives/Progress/Progress.stories.tsx +340 -0
  209. package/components/primitives/Progress/Progress.tsx +31 -0
  210. package/components/primitives/Progress/index.ts +1 -0
  211. package/components/primitives/ScrollArea/ScrollArea.stories.tsx +26 -0
  212. package/components/primitives/ScrollArea/ScrollArea.tsx +28 -0
  213. package/components/primitives/ScrollArea/index.ts +6 -0
  214. package/components/primitives/Select/Select.stories.tsx +288 -0
  215. package/components/primitives/Select/Select.tsx +162 -0
  216. package/components/primitives/Select/index.ts +22 -0
  217. package/components/primitives/Separator/Separator.stories.tsx +264 -0
  218. package/components/primitives/Separator/Separator.tsx +48 -0
  219. package/components/primitives/Separator/index.ts +7 -0
  220. package/components/primitives/Sidebar/Sidebar.stories.tsx +358 -0
  221. package/components/primitives/Sidebar/Sidebar.tsx +317 -0
  222. package/components/primitives/Sidebar/index.ts +41 -0
  223. package/components/primitives/Table/Table.stories.tsx +389 -0
  224. package/components/primitives/Table/Table.tsx +191 -0
  225. package/components/primitives/Table/index.ts +26 -0
  226. package/components/primitives/Tabs/Tabs.stories.tsx +129 -0
  227. package/components/primitives/Tabs/Tabs.tsx +70 -0
  228. package/components/primitives/Tabs/index.ts +13 -0
  229. package/components/primitives/Textarea/Textarea.stories.tsx +358 -0
  230. package/components/primitives/Textarea/Textarea.tsx +91 -0
  231. package/components/primitives/Textarea/index.ts +7 -0
  232. package/components/primitives/ToggleGroup/ToggleGroup.stories.tsx +87 -0
  233. package/components/primitives/ToggleGroup/ToggleGroup.tsx +52 -0
  234. package/components/primitives/ToggleGroup/index.ts +6 -0
  235. package/components/primitives/Tooltip/Tooltip.stories.tsx +336 -0
  236. package/components/primitives/Tooltip/Tooltip.tsx +78 -0
  237. package/components/primitives/Tooltip/index.ts +10 -0
  238. package/components/primitives/index.ts +34 -0
  239. package/components/ui/accordion.tsx +66 -0
  240. package/components/ui/alert-dialog.tsx +157 -0
  241. package/components/ui/alert.tsx +66 -0
  242. package/components/ui/avatar.tsx +53 -0
  243. package/components/ui/badge.tsx +46 -0
  244. package/components/ui/button.tsx +60 -0
  245. package/components/ui/card.tsx +117 -0
  246. package/components/ui/carousel.tsx +241 -0
  247. package/components/ui/chart.tsx +334 -0
  248. package/components/ui/checkbox.tsx +32 -0
  249. package/components/ui/collapsible.tsx +33 -0
  250. package/components/ui/command.tsx +184 -0
  251. package/components/ui/dialog.tsx +143 -0
  252. package/components/ui/drawer.tsx +118 -0
  253. package/components/ui/dropdown-menu.tsx +257 -0
  254. package/components/ui/hover-card.tsx +44 -0
  255. package/components/ui/input-group.tsx +170 -0
  256. package/components/ui/input.tsx +48 -0
  257. package/components/ui/label.tsx +26 -0
  258. package/components/ui/popover.tsx +33 -0
  259. package/components/ui/progress.tsx +31 -0
  260. package/components/ui/scroll-area.tsx +58 -0
  261. package/components/ui/select.tsx +187 -0
  262. package/components/ui/separator.tsx +31 -0
  263. package/components/ui/sidebar.tsx +577 -0
  264. package/components/ui/table.tsx +120 -0
  265. package/components/ui/tabs.tsx +66 -0
  266. package/components/ui/textarea.tsx +46 -0
  267. package/components/ui/toggle-group.tsx +83 -0
  268. package/components/ui/toggle.tsx +47 -0
  269. package/components/ui/tooltip.tsx +61 -0
  270. package/dist/index.cjs +7389 -0
  271. package/dist/index.cjs.map +1 -0
  272. package/dist/index.css +75 -0
  273. package/dist/index.css.map +1 -0
  274. package/dist/index.js +7160 -0
  275. package/dist/index.js.map +1 -0
  276. package/hooks/useAIDocReviewer.d.ts +0 -0
  277. package/lib/utils.ts +6 -0
  278. package/package.json +140 -0
  279. package/tokens/color/base.json +14 -0
  280. package/tokens/color/dark.json +40 -0
  281. package/tokens/color/green.json +21 -0
  282. package/tokens/color/light.json +52 -0
  283. package/tokens/color/neutral.json +20 -0
  284. package/tokens/color/violet.json +21 -0
  285. package/tokens/spacing.json +22 -0
  286. package/utils/ai-editor/format-date.ts +41 -0
  287. package/utils/ai-editor/index.ts +22 -0
  288. package/utils/ai-editor/type-guards.ts +72 -0
  289. package/utils/ai-editor/validation.ts +130 -0
  290. package/utils/editor-annotations.ts +122 -0
@@ -0,0 +1,186 @@
1
+ import * as React from "react"
2
+ import {
3
+ Conversation,
4
+ ConversationContent,
5
+ ConversationEmptyState,
6
+ ConversationScrollButton,
7
+ type ConversationProps,
8
+ } from "@/components/ai-elements/conversation"
9
+ import { type AIMessage } from "@/components/composites/AgentMessage"
10
+ import { UserMessage } from "@/components/composites/UserMessage"
11
+ import { SpecialistMessage } from "@/components/composites/SpecialistMessage"
12
+ import { OrchestratorMessage } from "@/components/composites/OrchestratorMessage"
13
+ import { ToolCallDisplay } from "@/components/composites/ToolCallDisplay"
14
+ import type { SubAgent } from "@/components/composites/AgentIndicator"
15
+
16
+ /**
17
+ * AIConversation Section
18
+ *
19
+ * A section-level component specifically designed for AI agent conversations.
20
+ * Uses the Conversation AI element with AgentMessage blocks to display
21
+ * multi-agent workflows with tool calls and sub-agent indicators.
22
+ *
23
+ * Based on reference implementation from deep-agents-ui ChatInterface.
24
+ */
25
+
26
+ export interface AIConversationProps
27
+ extends Omit<ConversationProps, "children"> {
28
+ /**
29
+ * Array of AI messages to display
30
+ */
31
+ messages: AIMessage[]
32
+ /**
33
+ * Whether to show avatars for messages
34
+ */
35
+ showAvatars?: boolean
36
+ /**
37
+ * Handler for sub-agent selection
38
+ */
39
+ onSelectSubAgent?: (subAgent: SubAgent) => void
40
+ /**
41
+ * Currently selected sub-agent
42
+ */
43
+ selectedSubAgent?: SubAgent | null
44
+ /**
45
+ * Empty state configuration
46
+ */
47
+ emptyState?: {
48
+ title?: string
49
+ description?: string
50
+ icon?: React.ReactNode
51
+ }
52
+ }
53
+
54
+ /**
55
+ * AIConversation component - displays AI agent conversations with tool calls and sub-agents
56
+ */
57
+ export const AIConversation = React.memo<AIConversationProps>(
58
+ ({
59
+ messages,
60
+ showAvatars = true,
61
+ onSelectSubAgent,
62
+ selectedSubAgent,
63
+ emptyState,
64
+ ...conversationProps
65
+ }) => {
66
+ const isEmpty = React.useMemo(
67
+ () => messages.length === 0,
68
+ [messages.length]
69
+ )
70
+
71
+ const emptyStateTitle = React.useMemo(
72
+ () => emptyState?.title || "No conversation yet",
73
+ [emptyState?.title]
74
+ )
75
+
76
+ const emptyStateDescription = React.useMemo(
77
+ () =>
78
+ emptyState?.description ||
79
+ "Start a conversation to see AI agent interactions",
80
+ [emptyState?.description]
81
+ )
82
+
83
+ const renderedMessages = React.useMemo(
84
+ () =>
85
+ messages.map((message) => {
86
+ // Render based on role field
87
+ if (message.role === "user") {
88
+ return (
89
+ <UserMessage
90
+ key={message.id}
91
+ message={{
92
+ id: message.id,
93
+ content: message.content,
94
+ avatarSrc: message.avatarSrc,
95
+ avatarName: message.avatarName,
96
+ }}
97
+ showAvatar={showAvatars}
98
+ />
99
+ )
100
+ }
101
+
102
+ if (message.role === "orchestrator") {
103
+ // Extract sub-agents from the message
104
+ const subAgents = message.subAgents || []
105
+
106
+ // Filter tool calls that aren't "task" type (those become sub-agents)
107
+ const directToolCalls =
108
+ message.toolCalls?.filter(
109
+ (tc) => tc.name !== "task"
110
+ ) || []
111
+
112
+ return (
113
+ <OrchestratorMessage
114
+ key={message.id}
115
+ message={{
116
+ id: message.id,
117
+ content: message.content,
118
+ avatarSrc: message.avatarSrc,
119
+ avatarName: message.avatarName,
120
+ }}
121
+ showAvatar={showAvatars}
122
+ >
123
+ {/* Render direct tool calls */}
124
+ {directToolCalls.map((tc) => (
125
+ <ToolCallDisplay key={tc.id} toolCall={tc} />
126
+ ))}
127
+
128
+ {/* Render specialist sub-agents */}
129
+ {subAgents.map((subAgent) => (
130
+ <SpecialistMessage
131
+ key={subAgent.id}
132
+ message={{
133
+ id: subAgent.id,
134
+ name: subAgent.subAgentName,
135
+ description: typeof subAgent.input === 'string' ? subAgent.input : JSON.stringify(subAgent.input),
136
+ content: typeof subAgent.output === 'string' ? subAgent.output : (subAgent.output ? JSON.stringify(subAgent.output) : ''),
137
+ status: subAgent.status,
138
+ toolCalls: [],
139
+ }}
140
+ showAvatar={showAvatars}
141
+ isNested={true}
142
+ />
143
+ ))}
144
+ </OrchestratorMessage>
145
+ )
146
+ }
147
+
148
+ // Default to specialist message for any other AI messages
149
+ return (
150
+ <SpecialistMessage
151
+ key={message.id}
152
+ message={{
153
+ id: message.id,
154
+ name: message.avatarName || "Agent",
155
+ content: message.content,
156
+ toolCalls: message.toolCalls?.filter((tc) => tc.name !== "task"),
157
+ status: "completed",
158
+ }}
159
+ showAvatar={showAvatars}
160
+ isNested={false}
161
+ />
162
+ )
163
+ }),
164
+ [messages, showAvatars]
165
+ )
166
+
167
+ return (
168
+ <Conversation {...conversationProps}>
169
+ <ConversationContent>
170
+ {isEmpty ? (
171
+ <ConversationEmptyState
172
+ title={emptyStateTitle}
173
+ description={emptyStateDescription}
174
+ icon={emptyState?.icon}
175
+ />
176
+ ) : (
177
+ renderedMessages
178
+ )}
179
+ </ConversationContent>
180
+ <ConversationScrollButton />
181
+ </Conversation>
182
+ )
183
+ }
184
+ )
185
+
186
+ AIConversation.displayName = "AIConversation"
@@ -0,0 +1,8 @@
1
+ /**
2
+ * AIConversation Section
3
+ *
4
+ * Central export point for the AIConversation section component and its related types.
5
+ */
6
+ export { AIConversation } from './AIConversation'
7
+
8
+ export type { AIConversationProps } from './AIConversation'
@@ -0,0 +1,63 @@
1
+ import type { Meta, StoryObj } from '@storybook/react'
2
+ import { AppSidebar } from './AppSidebar'
3
+ import { SidebarProvider } from '@/components/primitives/Sidebar'
4
+
5
+ const meta = {
6
+ title: 'Blocks/AppSidebar',
7
+ component: AppSidebar,
8
+ tags: ['autodocs'],
9
+ parameters: { layout: 'fullscreen' },
10
+ } satisfies Meta<typeof AppSidebar>
11
+
12
+ export default meta
13
+ type Story = StoryObj<typeof meta>
14
+
15
+ const mainNav = [
16
+ { title: 'Dashboard', url: '#', icon: 'layout-dashboard', isActive: true },
17
+ { title: 'Projects', url: '#', icon: 'folder' },
18
+ { title: 'Tasks', url: '#', icon: 'check-square' },
19
+ ]
20
+
21
+ const secondaryNav = [
22
+ { title: 'Settings', url: '#', icon: 'settings' },
23
+ { title: 'Help', url: '#', icon: 'help-circle' },
24
+ ]
25
+
26
+ const user = {
27
+ name: 'John Doe',
28
+ email: 'john@example.com',
29
+ avatar: 'https://github.com/shadcn.png',
30
+ }
31
+
32
+ export const Default: Story = {
33
+ render: () => (
34
+ <SidebarProvider>
35
+ <AppSidebar
36
+ logo={{ icon: 'command', text: 'Acme Inc.', href: '/' }}
37
+ mainNavigation={mainNav}
38
+ user={user}
39
+ />
40
+ </SidebarProvider>
41
+ ),
42
+ }
43
+
44
+ export const Complete: Story = {
45
+ render: () => (
46
+ <SidebarProvider>
47
+ <AppSidebar
48
+ logo={{ icon: 'command', text: 'Acme Inc.', href: '/' }}
49
+ mainNavigation={mainNav}
50
+ secondaryNavigation={secondaryNav}
51
+ documents={[
52
+ { title: 'Project A', url: '#', icon: 'file' },
53
+ { title: 'Project B', url: '#', icon: 'file' },
54
+ ]}
55
+ user={user}
56
+ userActions={[
57
+ { label: 'Profile', onClick: () => {} },
58
+ { label: 'Logout', onClick: () => {} },
59
+ ]}
60
+ />
61
+ </SidebarProvider>
62
+ ),
63
+ }
@@ -0,0 +1,87 @@
1
+ import * as React from "react"
2
+ import {
3
+ Sidebar,
4
+ SidebarHeader,
5
+ SidebarContent,
6
+ SidebarFooter,
7
+ SidebarMenu,
8
+ SidebarMenuItem,
9
+ SidebarMenuButton,
10
+ SidebarGroup,
11
+ SidebarGroupContent,
12
+ SidebarGroupLabel,
13
+ } from "@/components/primitives/Sidebar"
14
+ import { Icon } from "@/components/primitives/Icon"
15
+ import { NavigationList, type NavigationItem } from "@/components/composites/NavigationList"
16
+ import { NavUser } from "@/components/composites/NavUser"
17
+
18
+ export interface AppSidebarProps extends React.ComponentPropsWithoutRef<typeof Sidebar> {
19
+ logo?: {
20
+ icon: string
21
+ text: string
22
+ href: string
23
+ }
24
+ mainNavigation: NavigationItem[]
25
+ secondaryNavigation?: NavigationItem[]
26
+ documents?: NavigationItem[]
27
+ user: {
28
+ name: string
29
+ email: string
30
+ avatar?: string
31
+ }
32
+ userActions?: { label: string; onClick: () => void }[]
33
+ }
34
+
35
+ export const AppSidebar = React.memo<AppSidebarProps>(
36
+ ({ logo, mainNavigation, secondaryNavigation, documents, user, userActions, ...props }) => {
37
+ return (
38
+ <Sidebar {...props} variant="inset" collapsible="offcanvas">
39
+ <SidebarHeader>
40
+ {logo && (
41
+ <SidebarMenu>
42
+ <SidebarMenuItem>
43
+ <SidebarMenuButton asChild className="data-[slot=sidebar-menu-button]:!p-1.5">
44
+ <a href={logo.href}>
45
+ <Icon name={logo.icon} className="!size-5" />
46
+ <span className="text-base font-semibold">{logo.text}</span>
47
+ </a>
48
+ </SidebarMenuButton>
49
+ </SidebarMenuItem>
50
+ </SidebarMenu>
51
+ )}
52
+ </SidebarHeader>
53
+
54
+ <SidebarContent>
55
+ <SidebarGroup>
56
+ <SidebarGroupContent>
57
+ <NavigationList items={mainNavigation} />
58
+ </SidebarGroupContent>
59
+ </SidebarGroup>
60
+
61
+ {documents && documents.length > 0 && (
62
+ <SidebarGroup>
63
+ <SidebarGroupLabel>Documents</SidebarGroupLabel>
64
+ <SidebarGroupContent>
65
+ <NavigationList items={documents} />
66
+ </SidebarGroupContent>
67
+ </SidebarGroup>
68
+ )}
69
+
70
+ {secondaryNavigation && secondaryNavigation.length > 0 && (
71
+ <SidebarGroup>
72
+ <SidebarGroupContent className="mt-auto">
73
+ <NavigationList items={secondaryNavigation} />
74
+ </SidebarGroupContent>
75
+ </SidebarGroup>
76
+ )}
77
+ </SidebarContent>
78
+
79
+ <SidebarFooter>
80
+ <NavUser user={user} actions={userActions} />
81
+ </SidebarFooter>
82
+ </Sidebar>
83
+ )
84
+ }
85
+ )
86
+
87
+ AppSidebar.displayName = "AppSidebar"
@@ -0,0 +1,2 @@
1
+ export { AppSidebar } from './AppSidebar'
2
+ export type { AppSidebarProps } from './AppSidebar'
@@ -0,0 +1,341 @@
1
+ /**
2
+ * DocumentEditorWithComments Stories
3
+ *
4
+ * Demonstrates the DocumentEditorWithComments section with various annotation types
5
+ */
6
+
7
+ import type { Meta, StoryObj } from '@storybook/react'
8
+ import type { JSONContent } from '@tiptap/core'
9
+ import { DocumentEditorWithComments } from './DocumentEditorWithComments'
10
+ import type { Annotation } from '@/types/ai-editor'
11
+
12
+ const meta: Meta<typeof DocumentEditorWithComments> = {
13
+ title: 'Blocks/DocumentEditorWithComments',
14
+ component: DocumentEditorWithComments,
15
+ parameters: {
16
+ layout: 'fullscreen',
17
+ },
18
+ tags: ['autodocs'],
19
+ }
20
+
21
+ export default meta
22
+ type Story = StoryObj<typeof DocumentEditorWithComments>
23
+
24
+ // Use the SAME document for all stories (like DocumentEditor block does)
25
+ const sampleContent: JSONContent = {
26
+ type: 'doc',
27
+ content: [
28
+ {
29
+ type: 'heading',
30
+ attrs: { level: 1 },
31
+ content: [{ type: 'text', text: 'Document Review Example' }],
32
+ },
33
+ {
34
+ type: 'paragraph',
35
+ content: [
36
+ { type: 'text', text: 'This is a sample document with various annotations. ' },
37
+ { type: 'text', text: 'Some text has comments, ' },
38
+ { type: 'text', text: 'some has suggestions, ' },
39
+ { type: 'text', text: 'and some has block additions.' },
40
+ ],
41
+ },
42
+ {
43
+ type: 'paragraph',
44
+ content: [
45
+ { type: 'text', text: 'The editor supports inline annotations for comments and suggestions. ' },
46
+ { type: 'text', text: 'Click on any highlighted text to see the annotation details.' },
47
+ ],
48
+ },
49
+ ],
50
+ }
51
+
52
+ // Annotations calculated for the sampleContent document
53
+ const commentAnnotations: Annotation[] = [
54
+ {
55
+ type: 'comment',
56
+ id: 'comment-1',
57
+ range: { from: 50, to: 70 },
58
+ createdAt: Date.now(),
59
+ userId: 'user-1',
60
+ data: {
61
+ thread: [
62
+ {
63
+ id: 'thread-1',
64
+ userId: 'user-1',
65
+ userName: 'John Doe',
66
+ contentRich: {
67
+ type: 'doc',
68
+ content: [
69
+ {
70
+ type: 'paragraph',
71
+ content: [{ type: 'text', text: 'This section needs clarification.' }],
72
+ },
73
+ ],
74
+ },
75
+ timestamp: Date.now(),
76
+ },
77
+ ],
78
+ },
79
+ },
80
+ ]
81
+
82
+ // Document specifically for suggestions demo
83
+ const suggestionsContent: JSONContent = {
84
+ type: 'doc',
85
+ content: [
86
+ {
87
+ type: 'heading',
88
+ attrs: { level: 2 },
89
+ content: [{ type: 'text', text: 'Text Modification Examples' }],
90
+ },
91
+ {
92
+ type: 'paragraph',
93
+ content: [
94
+ { type: 'text', text: 'This paragraph shows a ' },
95
+ { type: 'text', text: 'deletion example' },
96
+ { type: 'text', text: ' with strikethrough text.' },
97
+ ],
98
+ },
99
+ {
100
+ type: 'paragraph',
101
+ content: [
102
+ { type: 'text', text: 'This paragraph shows an ' },
103
+ { type: 'text', text: 'insertion example' },
104
+ { type: 'text', text: ' with green highlighted text.' },
105
+ ],
106
+ },
107
+ ],
108
+ }
109
+
110
+ const suggestionAnnotations: Annotation[] = [
111
+ {
112
+ type: 'suggestion',
113
+ id: 'diff-delete',
114
+ range: { from: 60, to: 76 }, // "deletion example"
115
+ createdAt: Date.now(),
116
+ userId: 'ai-1',
117
+ data: {
118
+ action: 'delete',
119
+ oldText: 'deletion example',
120
+ reason: 'Remove redundant text',
121
+ thread: [],
122
+ },
123
+ },
124
+ {
125
+ type: 'suggestion',
126
+ id: 'diff-insert',
127
+ range: { from: 125, to: 142 }, // "insertion example"
128
+ createdAt: Date.now(),
129
+ userId: 'ai-1',
130
+ data: {
131
+ action: 'insert',
132
+ newText: 'insertion example',
133
+ reason: 'Add clarifying text',
134
+ thread: [],
135
+ },
136
+ },
137
+ ]
138
+
139
+ const mixedAnnotations: Annotation[] = [
140
+ ...commentAnnotations,
141
+ ...suggestionAnnotations,
142
+ ]
143
+
144
+ /**
145
+ * Default story with mixed annotations
146
+ */
147
+ export const Default: Story = {
148
+ args: {
149
+ content: sampleContent,
150
+ annotations: mixedAnnotations,
151
+ currentUserId: 'user-1',
152
+ currentUserName: 'John Doe',
153
+ readOnly: false,
154
+ onAnnotationAdd: (annotation) => console.log('Added annotation:', annotation),
155
+ onAnnotationUpdate: (annotation) => console.log('Updated annotation:', annotation),
156
+ },
157
+ }
158
+
159
+ /**
160
+ * Story with empty document
161
+ */
162
+ export const EmptyDocument: Story = {
163
+ args: {
164
+ content: {
165
+ type: 'doc',
166
+ content: [
167
+ {
168
+ type: 'paragraph',
169
+ content: [],
170
+ },
171
+ ],
172
+ },
173
+ annotations: [],
174
+ currentUserId: 'user-1',
175
+ currentUserName: 'John Doe',
176
+ readOnly: false,
177
+ },
178
+ }
179
+
180
+ /**
181
+ * Story in readonly mode (no interactions)
182
+ */
183
+ export const ReadonlyMode: Story = {
184
+ args: {
185
+ content: sampleContent,
186
+ annotations: commentAnnotations,
187
+ currentUserId: 'user-1',
188
+ currentUserName: 'John Doe',
189
+ readOnly: true,
190
+ },
191
+ }
192
+
193
+ /**
194
+ * Story with only comment annotations
195
+ */
196
+ export const CommentsOnly: Story = {
197
+ args: {
198
+ content: sampleContent,
199
+ annotations: commentAnnotations,
200
+ currentUserId: 'user-1',
201
+ currentUserName: 'John Doe',
202
+ readOnly: false,
203
+ onAnnotationAdd: (annotation) => console.log('Added annotation:', annotation),
204
+ onAnnotationUpdate: (annotation) => console.log('Updated annotation:', annotation),
205
+ },
206
+ }
207
+
208
+ /**
209
+ * Story with only suggestion annotations
210
+ * Shows deletion (red strikethrough) and insertion (green highlight)
211
+ */
212
+ export const SuggestionsOnly: Story = {
213
+ args: {
214
+ content: suggestionsContent,
215
+ annotations: suggestionAnnotations,
216
+ currentUserId: 'user-1',
217
+ currentUserName: 'John Doe',
218
+ readOnly: false,
219
+ onAnnotationAdd: (annotation) => console.log('Added annotation:', annotation),
220
+ onAnnotationUpdate: (annotation) => console.log('Updated annotation:', annotation),
221
+ },
222
+ }
223
+
224
+
225
+ /**
226
+ * Story with both comments and suggestions
227
+ * Shows yellow comment highlights and green/red suggestion highlights together
228
+ */
229
+ export const CommentsAndSuggestions: Story = {
230
+ args: {
231
+ content: {
232
+ type: 'doc',
233
+ content: [
234
+ {
235
+ type: 'heading',
236
+ attrs: { level: 2 },
237
+ content: [{ type: 'text', text: 'Document with Comments and Suggestions' }],
238
+ },
239
+ {
240
+ type: 'paragraph',
241
+ content: [
242
+ { type: 'text', text: 'This paragraph has a comment annotation. ' },
243
+ { type: 'text', text: 'Click the highlighted text to view the discussion.' },
244
+ ],
245
+ },
246
+ {
247
+ type: 'paragraph',
248
+ content: [
249
+ { type: 'text', text: 'This paragraph shows a ' },
250
+ { type: 'text', text: 'deletion suggestion' },
251
+ { type: 'text', text: ' with red strikethrough.' },
252
+ ],
253
+ },
254
+ {
255
+ type: 'paragraph',
256
+ content: [
257
+ { type: 'text', text: 'This paragraph shows an ' },
258
+ { type: 'text', text: 'insertion suggestion' },
259
+ { type: 'text', text: ' with green highlight.' },
260
+ ],
261
+ },
262
+ ],
263
+ },
264
+ annotations: [
265
+ {
266
+ type: 'comment',
267
+ id: 'comment-1',
268
+ range: { from: 62, to: 80 }, // "comment annotation"
269
+ createdAt: Date.now(),
270
+ userId: 'user-1',
271
+ data: {
272
+ thread: [
273
+ {
274
+ id: 'thread-1',
275
+ userId: 'user-1',
276
+ userName: 'John Doe',
277
+ avatarSrc: 'https://api.dicebear.com/7.x/avataaars/svg?seed=John',
278
+ contentRich: {
279
+ type: 'doc',
280
+ content: [
281
+ {
282
+ type: 'paragraph',
283
+ content: [{ type: 'text', text: 'This section needs clarification.' }],
284
+ },
285
+ ],
286
+ },
287
+ timestamp: Date.now() - 3600000,
288
+ },
289
+ {
290
+ id: 'thread-2',
291
+ userId: 'user-2',
292
+ userName: 'Jane Smith',
293
+ avatarSrc: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Jane',
294
+ contentRich: {
295
+ type: 'doc',
296
+ content: [
297
+ {
298
+ type: 'paragraph',
299
+ content: [{ type: 'text', text: 'I agree, let me add more details.' }],
300
+ },
301
+ ],
302
+ },
303
+ timestamp: Date.now() - 1800000,
304
+ },
305
+ ],
306
+ },
307
+ },
308
+ {
309
+ type: 'suggestion',
310
+ id: 'suggestion-delete',
311
+ range: { from: 157, to: 176 }, // "deletion suggestion"
312
+ createdAt: Date.now(),
313
+ userId: 'ai-1',
314
+ data: {
315
+ action: 'delete',
316
+ oldText: 'deletion suggestion',
317
+ reason: 'Remove redundant text',
318
+ thread: [],
319
+ },
320
+ },
321
+ {
322
+ type: 'suggestion',
323
+ id: 'suggestion-insert',
324
+ range: { from: 226, to: 246 }, // "insertion suggestion"
325
+ createdAt: Date.now(),
326
+ userId: 'ai-1',
327
+ data: {
328
+ action: 'insert',
329
+ newText: 'insertion suggestion',
330
+ reason: 'Add clarifying text',
331
+ thread: [],
332
+ },
333
+ },
334
+ ],
335
+ currentUserId: 'user-1',
336
+ currentUserName: 'John Doe',
337
+ readOnly: false,
338
+ onAnnotationAdd: (annotation) => console.log('Added annotation:', annotation),
339
+ onAnnotationUpdate: (annotation) => console.log('Updated annotation:', annotation),
340
+ },
341
+ }