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
File without changes
package/lib/utils.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx"
2
+ import { twMerge } from "tailwind-merge"
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs))
6
+ }
package/package.json ADDED
@@ -0,0 +1,140 @@
1
+ {
2
+ "name": "ai-design-system",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "AI-powered design system with React components, built with Tailwind CSS and Radix UI",
7
+ "main": "./dist/index.js",
8
+ "module": "./dist/index.mjs",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.mjs",
14
+ "require": "./dist/index.js"
15
+ },
16
+ "./styles": "./dist/styles.css"
17
+ },
18
+ "files": [
19
+ "dist",
20
+ "components",
21
+ "lib",
22
+ "hooks",
23
+ "utils",
24
+ "tokens",
25
+ "README.md"
26
+ ],
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/bizmatters/ai-design-system.git"
33
+ },
34
+ "keywords": [
35
+ "react",
36
+ "components",
37
+ "design-system",
38
+ "ui",
39
+ "tailwind",
40
+ "radix-ui",
41
+ "ai",
42
+ "typescript"
43
+ ],
44
+ "author": "Bizmatters",
45
+ "license": "MIT",
46
+ "dependencies": {
47
+ "@radix-ui/react-accordion": "^1.2.12",
48
+ "@radix-ui/react-alert-dialog": "^1.1.15",
49
+ "@radix-ui/react-avatar": "^1.1.11",
50
+ "@radix-ui/react-checkbox": "^1.3.3",
51
+ "@radix-ui/react-collapsible": "^1.1.12",
52
+ "@radix-ui/react-dialog": "^1.1.15",
53
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
54
+ "@radix-ui/react-hover-card": "^1.1.15",
55
+ "@radix-ui/react-label": "^2.1.8",
56
+ "@radix-ui/react-popover": "^1.1.15",
57
+ "@radix-ui/react-progress": "^1.1.8",
58
+ "@radix-ui/react-scroll-area": "^1.2.10",
59
+ "@radix-ui/react-select": "^2.2.6",
60
+ "@radix-ui/react-separator": "^1.1.8",
61
+ "@radix-ui/react-slot": "^1.2.4",
62
+ "@radix-ui/react-tabs": "^1.1.13",
63
+ "@radix-ui/react-toggle": "^1.1.10",
64
+ "@radix-ui/react-toggle-group": "^1.1.11",
65
+ "@radix-ui/react-tooltip": "^1.2.8",
66
+ "@radix-ui/react-use-controllable-state": "^1.2.2",
67
+ "@tanstack/react-table": "^8.21.3",
68
+ "@tiptap/core": "^3.10.7",
69
+ "@tiptap/extension-highlight": "^3.10.7",
70
+ "@tiptap/markdown": "^3.10.7",
71
+ "@tiptap/react": "^3.10.7",
72
+ "@tiptap/starter-kit": "^3.10.7",
73
+ "@xyflow/react": "^12.9.2",
74
+ "ai": "^5.0.87",
75
+ "class-variance-authority": "^0.7.1",
76
+ "clsx": "^2.1.1",
77
+ "cmdk": "^1.1.1",
78
+ "date-fns": "^4.1.0",
79
+ "embla-carousel-react": "^8.6.0",
80
+ "lucide-react": "^0.552.0",
81
+ "motion": "^12.23.24",
82
+ "nanoid": "^5.1.6",
83
+ "next": "16.0.1",
84
+ "react": "19.2.0",
85
+ "react-dom": "19.2.0",
86
+ "recharts": "^3.4.1",
87
+ "shiki": "^3.14.0",
88
+ "streamdown": "^1.4.0",
89
+ "tailwind-merge": "^3.3.1",
90
+ "tokenlens": "^1.3.1",
91
+ "use-stick-to-bottom": "^1.1.1",
92
+ "vaul": "^1.1.2"
93
+ },
94
+ "devDependencies": {
95
+ "@chromatic-com/storybook": "^4.1.2",
96
+ "@storybook/addon-a11y": "^10.0.4",
97
+ "@storybook/addon-docs": "^10.0.4",
98
+ "@storybook/addon-onboarding": "^10.0.4",
99
+ "@storybook/addon-vitest": "^10.0.4",
100
+ "@storybook/nextjs-vite": "^10.0.4",
101
+ "@storybook/test": "^8.6.14",
102
+ "@tailwindcss/postcss": "^4.1.16",
103
+ "@types/hast": "^3.0.4",
104
+ "@types/node": "^20",
105
+ "@types/react": "^19",
106
+ "@types/react-dom": "^19",
107
+ "@vitest/browser-playwright": "^4.0.7",
108
+ "@vitest/coverage-v8": "^4.0.7",
109
+ "eslint": "^9",
110
+ "eslint-config-next": "16.0.1",
111
+ "eslint-plugin-storybook": "^10.0.4",
112
+ "hast": "^1.0.0",
113
+ "ignore-loader": "^0.1.2",
114
+ "playwright": "^1.56.1",
115
+ "storybook": "^10.0.4",
116
+ "style-dictionary": "^5.1.1",
117
+ "tailwindcss": "^4.1.16",
118
+ "tsup": "^8.3.5",
119
+ "tw-animate-css": "^1.4.0",
120
+ "typescript": "^5",
121
+ "vitest": "^4.0.7"
122
+ },
123
+ "peerDependencies": {
124
+ "react": "^18.0.0 || ^19.0.0",
125
+ "react-dom": "^18.0.0 || ^19.0.0",
126
+ "next": "^14.0.0 || ^15.0.0 || ^16.0.0"
127
+ },
128
+ "scripts": {
129
+ "dev": "pnpm tokens:build && next dev",
130
+ "build": "pnpm tokens:build && pnpm prebuild && next build",
131
+ "build:lib": "pnpm tokens:build && tsup",
132
+ "prebuild": "bash scripts/run-all-validations.sh",
133
+ "start": "next start",
134
+ "lint": "eslint",
135
+ "tokens:build": "node build-tokens.js",
136
+ "tokens:watch": "style-dictionary build --watch",
137
+ "storybook": "storybook dev -p 6006",
138
+ "build-storybook": "storybook build"
139
+ }
140
+ }
@@ -0,0 +1,14 @@
1
+ {
2
+ "color": {
3
+ "base": {
4
+ "white": {
5
+ "$value": "oklch(1 0 0)",
6
+ "$type": "color"
7
+ },
8
+ "black": {
9
+ "$value": "oklch(0.145 0 0)",
10
+ "$type": "color"
11
+ }
12
+ }
13
+ }
14
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "color": {
3
+ "theme": {
4
+ "background": { "$value": "oklch(0.145 0 0)", "$type": "color" },
5
+ "foreground": { "$value": "oklch(0.985 0 0)", "$type": "color" },
6
+ "card": { "$value": "oklch(0.205 0 0)", "$type": "color" },
7
+ "card-foreground": { "$value": "oklch(0.985 0 0)", "$type": "color" },
8
+ "popover": { "$value": "oklch(0.205 0 0)", "$type": "color" },
9
+ "popover-foreground": { "$value": "oklch(0.985 0 0)", "$type": "color" },
10
+ "secondary": { "$value": "oklch(0.269 0 0)", "$type": "color" },
11
+ "secondary-foreground": { "$value": "oklch(0.985 0 0)", "$type": "color" },
12
+ "muted": { "$value": "oklch(0.269 0 0)", "$type": "color" },
13
+ "muted-foreground": { "$value": "oklch(0.708 0 0)", "$type": "color" },
14
+ "accent": { "$value": "oklch(0.269 0 0)", "$type": "color" },
15
+ "accent-foreground": { "$value": "oklch(0.985 0 0)", "$type": "color" },
16
+ "destructive": { "$value": "oklch(0.704 0.191 22.216)", "$type": "color" },
17
+ "border": { "$value": "oklch(1 0 0 / 10%)", "$type": "color" },
18
+ "input": { "$value": "oklch(1 0 0 / 15%)", "$type": "color" }
19
+ },
20
+ "sidebar": {
21
+ "background": { "$value": "oklch(0.205 0 0)", "$type": "color" },
22
+ "foreground": { "$value": "oklch(0.985 0 0)", "$type": "color" },
23
+ "primary-foreground": { "$value": "oklch(0.985 0 0)", "$type": "color" },
24
+ "accent": { "$value": "oklch(0.269 0 0)", "$type": "color" },
25
+ "accent-foreground": { "$value": "oklch(0.985 0 0)", "$type": "color" },
26
+ "border": { "$value": "oklch(1 0 0 / 10%)", "$type": "color" }
27
+ },
28
+ "annotation": {
29
+ "comment": { "$value": "oklch(0.35 0.12 95)", "$type": "color" },
30
+ "comment-foreground": { "$value": "oklch(0.85 0.12 95)", "$type": "color" },
31
+ "comment-border": { "$value": "oklch(0.55 0.15 95)", "$type": "color" },
32
+ "addition": { "$value": "oklch(0.30 0.12 145)", "$type": "color" },
33
+ "addition-foreground": { "$value": "oklch(0.75 0.12 145)", "$type": "color" },
34
+ "addition-border": { "$value": "oklch(0.50 0.15 145)", "$type": "color" },
35
+ "deletion": { "$value": "oklch(0.35 0.12 25)", "$type": "color" },
36
+ "deletion-foreground": { "$value": "oklch(0.75 0.15 25)", "$type": "color" },
37
+ "deletion-border": { "$value": "oklch(0.50 0.17 25)", "$type": "color" }
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "color": {
3
+ "theme": {
4
+ "primary": { "$value": "oklch(0.648 0.2 131.684)", "$type": "color" },
5
+ "primary-foreground": { "$value": "oklch(0.986 0.031 120.757)", "$type": "color" },
6
+ "ring": { "$value": "oklch(0.405 0.101 131.063)", "$type": "color" }
7
+ },
8
+ "chart": {
9
+ "1": { "$value": "oklch(0.871 0.15 154.449)", "$type": "color" },
10
+ "2": { "$value": "oklch(0.723 0.219 149.579)", "$type": "color" },
11
+ "3": { "$value": "oklch(0.627 0.194 149.214)", "$type": "color" },
12
+ "4": { "$value": "oklch(0.527 0.154 150.069)", "$type": "color" },
13
+ "5": { "$value": "oklch(0.448 0.119 151.328)", "$type": "color" }
14
+ },
15
+ "sidebar": {
16
+ "primary": { "$value": "oklch(0.768 0.233 130.85)", "$type": "color" },
17
+ "primary-foreground": { "$value": "oklch(0.986 0.031 120.757)", "$type": "color" },
18
+ "ring": { "$value": "oklch(0.405 0.101 131.063)", "$type": "color" }
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,52 @@
1
+ {
2
+ "color": {
3
+ "theme": {
4
+ "background": { "$value": "{color.base.white}", "$type": "color" },
5
+ "foreground": { "$value": "{color.base.black}", "$type": "color" },
6
+ "card": { "$value": "{color.base.white}", "$type": "color" },
7
+ "card-foreground": { "$value": "{color.base.black}", "$type": "color" },
8
+ "popover": { "$value": "{color.base.white}", "$type": "color" },
9
+ "popover-foreground": { "$value": "{color.base.black}", "$type": "color" },
10
+ "primary": { "$value": "oklch(0.205 0 0)", "$type": "color" },
11
+ "primary-foreground": { "$value": "oklch(0.985 0 0)", "$type": "color" },
12
+ "secondary": { "$value": "oklch(0.97 0 0)", "$type": "color" },
13
+ "secondary-foreground": { "$value": "oklch(0.205 0 0)", "$type": "color" },
14
+ "muted": { "$value": "oklch(0.97 0 0)", "$type": "color" },
15
+ "muted-foreground": { "$value": "oklch(0.556 0 0)", "$type": "color" },
16
+ "accent": { "$value": "oklch(0.97 0 0)", "$type": "color" },
17
+ "accent-foreground": { "$value": "oklch(0.205 0 0)", "$type": "color" },
18
+ "destructive": { "$value": "oklch(0.577 0.245 27.325)", "$type": "color" },
19
+ "border": { "$value": "oklch(0.922 0 0)", "$type": "color" },
20
+ "input": { "$value": "oklch(0.922 0 0)", "$type": "color" },
21
+ "ring": { "$value": "oklch(0.708 0 0)", "$type": "color" }
22
+ },
23
+ "chart": {
24
+ "1": { "$value": "oklch(0.646 0.222 41.116)", "$type": "color" },
25
+ "2": { "$value": "oklch(0.6 0.118 184.704)", "$type": "color" },
26
+ "3": { "$value": "oklch(0.398 0.07 227.392)", "$type": "color" },
27
+ "4": { "$value": "oklch(0.828 0.189 84.429)", "$type": "color" },
28
+ "5": { "$value": "oklch(0.769 0.188 70.08)", "$type": "color" }
29
+ },
30
+ "sidebar": {
31
+ "background": { "$value": "oklch(0.985 0 0)", "$type": "color" },
32
+ "foreground": { "$value": "{color.base.black}", "$type": "color" },
33
+ "primary": { "$value": "oklch(0.205 0 0)", "$type": "color" },
34
+ "primary-foreground": { "$value": "oklch(0.985 0 0)", "$type": "color" },
35
+ "accent": { "$value": "oklch(0.97 0 0)", "$type": "color" },
36
+ "accent-foreground": { "$value": "oklch(0.205 0 0)", "$type": "color" },
37
+ "border": { "$value": "oklch(0.922 0 0)", "$type": "color" },
38
+ "ring": { "$value": "oklch(0.708 0 0)", "$type": "color" }
39
+ },
40
+ "annotation": {
41
+ "comment": { "$value": "oklch(0.95 0.15 95)", "$type": "color" },
42
+ "comment-foreground": { "$value": "oklch(0.45 0.15 95)", "$type": "color" },
43
+ "comment-border": { "$value": "oklch(0.65 0.18 95)", "$type": "color" },
44
+ "addition": { "$value": "oklch(0.85 0.15 145)", "$type": "color" },
45
+ "addition-foreground": { "$value": "oklch(0.35 0.15 145)", "$type": "color" },
46
+ "addition-border": { "$value": "oklch(0.55 0.18 145)", "$type": "color" },
47
+ "deletion": { "$value": "oklch(0.88 0.15 25)", "$type": "color" },
48
+ "deletion-foreground": { "$value": "oklch(0.45 0.18 25)", "$type": "color" },
49
+ "deletion-border": { "$value": "oklch(0.58 0.20 25)", "$type": "color" }
50
+ }
51
+ }
52
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "color": {
3
+ "theme": {
4
+ "primary": { "$value": "oklch(0.922 0 0)", "$type": "color" },
5
+ "primary-foreground": { "$value": "oklch(0.205 0 0)", "$type": "color" },
6
+ "ring": { "$value": "oklch(0.556 0 0)", "$type": "color" }
7
+ },
8
+ "chart": {
9
+ "1": { "$value": "oklch(0.488 0.243 264.376)", "$type": "color" },
10
+ "2": { "$value": "oklch(0.696 0.17 162.48)", "$type": "color" },
11
+ "3": { "$value": "oklch(0.769 0.188 70.08)", "$type": "color" },
12
+ "4": { "$value": "oklch(0.627 0.265 303.9)", "$type": "color" },
13
+ "5": { "$value": "oklch(0.645 0.246 16.439)", "$type": "color" }
14
+ },
15
+ "sidebar": {
16
+ "primary": { "$value": "oklch(0.488 0.243 264.376)", "$type": "color" },
17
+ "ring": { "$value": "oklch(0.556 0 0)", "$type": "color" }
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "color": {
3
+ "theme": {
4
+ "primary": { "$value": "oklch(0.606 0.25 292.717)", "$type": "color" },
5
+ "primary-foreground": { "$value": "oklch(0.969 0.016 293.756)", "$type": "color" },
6
+ "ring": { "$value": "oklch(0.38 0.189 293.745)", "$type": "color" }
7
+ },
8
+ "chart": {
9
+ "1": { "$value": "oklch(0.811 0.111 293.571)", "$type": "color" },
10
+ "2": { "$value": "oklch(0.606 0.25 292.717)", "$type": "color" },
11
+ "3": { "$value": "oklch(0.541 0.281 293.009)", "$type": "color" },
12
+ "4": { "$value": "oklch(0.491 0.27 292.581)", "$type": "color" },
13
+ "5": { "$value": "oklch(0.432 0.232 292.759)", "$type": "color" }
14
+ },
15
+ "sidebar": {
16
+ "primary": { "$value": "oklch(0.606 0.25 292.717)", "$type": "color" },
17
+ "primary-foreground": { "$value": "oklch(0.969 0.016 293.756)", "$type": "color" },
18
+ "ring": { "$value": "oklch(0.38 0.189 293.745)", "$type": "color" }
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "spacing": {
3
+ "radius": {
4
+ "$type": "dimension",
5
+ "base": { "$value": "0.625rem" },
6
+ "sm": { "$value": "{spacing.radius.base} - 4px" },
7
+ "md": { "$value": "{spacing.radius.base} - 2px" },
8
+ "lg": { "$value": "{spacing.radius.base}" },
9
+ "xl": { "$value": "{spacing.radius.base} + 4px" }
10
+ },
11
+ "sidebar": {
12
+ "$type": "dimension",
13
+ "width": { "$value": "16rem" },
14
+ "width-mobile": { "$value": "18rem" },
15
+ "width-icon": { "$value": "3rem" }
16
+ },
17
+ "header": {
18
+ "$type": "dimension",
19
+ "height": { "$value": "3.5rem" }
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Format Comment Date Utility
3
+ *
4
+ * Formats timestamps as relative time for comment display
5
+ */
6
+
7
+ import { formatDistanceToNow } from 'date-fns'
8
+
9
+ /**
10
+ * Formats a timestamp as relative time
11
+ *
12
+ * @param date - Date object or Unix timestamp (number) to format
13
+ * @returns Formatted string like "5m", "2h", "3d", "2w", "3mo", "1y"
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * formatCommentDate(new Date(Date.now() - 5 * 60 * 1000)) // "5m"
18
+ * formatCommentDate(Date.now() - 2 * 60 * 60 * 1000) // "2h"
19
+ * ```
20
+ */
21
+ export function formatCommentDate(date: Date | number): string {
22
+ const now = Date.now()
23
+ const timestamp = typeof date === 'number' ? date : date.getTime()
24
+ const diffMs = now - timestamp
25
+
26
+ const seconds = Math.floor(diffMs / 1000)
27
+ const minutes = Math.floor(seconds / 60)
28
+ const hours = Math.floor(minutes / 60)
29
+ const days = Math.floor(hours / 24)
30
+ const weeks = Math.floor(days / 7)
31
+ const months = Math.floor(days / 30)
32
+ const years = Math.floor(days / 365)
33
+
34
+ if (seconds < 60) return 'just now'
35
+ if (minutes < 60) return `${minutes}m`
36
+ if (hours < 24) return `${hours}h`
37
+ if (days < 7) return `${days}d`
38
+ if (weeks < 4) return `${weeks}w`
39
+ if (months < 12) return `${months}mo`
40
+ return `${years}y`
41
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * AI Editor Utilities
3
+ *
4
+ * Central export point for all AI Editor utility functions
5
+ */
6
+
7
+ // Type guards
8
+ export {
9
+ isCommentAnnotation,
10
+ isSuggestionAnnotation,
11
+ isBlockAdditionAnnotation,
12
+ } from './type-guards'
13
+
14
+ // Validation utilities
15
+ export {
16
+ validateRange,
17
+ validateAnnotation,
18
+ validateAnnotations,
19
+ } from './validation'
20
+
21
+ // Date formatting
22
+ export { formatCommentDate } from './format-date'
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Type Guards for AI Editor Annotations
3
+ *
4
+ * Provides runtime type checking for discriminated union types
5
+ */
6
+
7
+ import type {
8
+ Annotation,
9
+ CommentAnnotation,
10
+ SuggestionAnnotation,
11
+ BlockAdditionAnnotation,
12
+ } from '../../types/ai-editor'
13
+
14
+ /**
15
+ * Type guard to check if annotation is a CommentAnnotation
16
+ *
17
+ * @param annotation - Annotation to check
18
+ * @returns True if annotation is a CommentAnnotation
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * if (isCommentAnnotation(annotation)) {
23
+ * // TypeScript knows annotation.data.thread exists
24
+ * console.log(annotation.data.thread.length)
25
+ * }
26
+ * ```
27
+ */
28
+ export function isCommentAnnotation(
29
+ annotation: Annotation
30
+ ): annotation is CommentAnnotation {
31
+ return annotation.type === 'comment'
32
+ }
33
+
34
+ /**
35
+ * Type guard to check if annotation is a SuggestionAnnotation
36
+ *
37
+ * @param annotation - Annotation to check
38
+ * @returns True if annotation is a SuggestionAnnotation
39
+ *
40
+ * @example
41
+ * ```ts
42
+ * if (isSuggestionAnnotation(annotation)) {
43
+ * // TypeScript knows annotation.data.action exists
44
+ * console.log(annotation.data.action)
45
+ * }
46
+ * ```
47
+ */
48
+ export function isSuggestionAnnotation(
49
+ annotation: Annotation
50
+ ): annotation is SuggestionAnnotation {
51
+ return annotation.type === 'suggestion'
52
+ }
53
+
54
+ /**
55
+ * Type guard to check if annotation is a BlockAdditionAnnotation
56
+ *
57
+ * @param annotation - Annotation to check
58
+ * @returns True if annotation is a BlockAdditionAnnotation
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * if (isBlockAdditionAnnotation(annotation)) {
63
+ * // TypeScript knows annotation.data.content exists
64
+ * console.log(annotation.data.content)
65
+ * }
66
+ * ```
67
+ */
68
+ export function isBlockAdditionAnnotation(
69
+ annotation: Annotation
70
+ ): annotation is BlockAdditionAnnotation {
71
+ return annotation.type === 'block-addition'
72
+ }
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Validation Utilities for AI Editor
3
+ *
4
+ * Provides runtime validation for annotations and ranges
5
+ */
6
+
7
+ import type { Annotation, Range } from '../../types/ai-editor'
8
+ import {
9
+ isCommentAnnotation,
10
+ isSuggestionAnnotation,
11
+ isBlockAdditionAnnotation,
12
+ } from './type-guards'
13
+
14
+ /**
15
+ * Validates a range object
16
+ *
17
+ * @param range - Range to validate
18
+ * @param documentLength - Total length of the document
19
+ * @returns True if range is valid
20
+ */
21
+ export function validateRange(range: Range, documentLength: number): boolean {
22
+ // Check range bounds
23
+ if (range.from < 0 || range.to > documentLength) {
24
+ console.error('Range out of bounds:', range, 'Document length:', documentLength)
25
+ return false
26
+ }
27
+
28
+ // Check range order
29
+ if (range.from >= range.to) {
30
+ console.error('Invalid range: from must be less than to:', range)
31
+ return false
32
+ }
33
+
34
+ return true
35
+ }
36
+
37
+ /**
38
+ * Validates an annotation object
39
+ *
40
+ * @param annotation - Annotation to validate
41
+ * @param documentLength - Total length of the document
42
+ * @returns True if annotation is valid
43
+ */
44
+ export function validateAnnotation(
45
+ annotation: Annotation,
46
+ documentLength: number
47
+ ): boolean {
48
+ // Validate range
49
+ if (!validateRange(annotation.range, documentLength)) {
50
+ return false
51
+ }
52
+
53
+ // Validate type-specific data
54
+ if (isCommentAnnotation(annotation)) {
55
+ if (!annotation.data.thread || annotation.data.thread.length === 0) {
56
+ console.error('Comment annotation must have at least one comment:', annotation)
57
+ return false
58
+ }
59
+ } else if (isSuggestionAnnotation(annotation)) {
60
+ if (!annotation.data.reason) {
61
+ console.error('Suggestion annotation must have a reason:', annotation)
62
+ return false
63
+ }
64
+
65
+ // Validate action-specific requirements
66
+ if (annotation.data.action === 'modify') {
67
+ if (!annotation.data.oldText || !annotation.data.newText) {
68
+ console.error(
69
+ 'Modify suggestion must have both oldText and newText:',
70
+ annotation
71
+ )
72
+ return false
73
+ }
74
+ } else if (annotation.data.action === 'delete') {
75
+ if (!annotation.data.oldText) {
76
+ console.error('Delete suggestion must have oldText:', annotation)
77
+ return false
78
+ }
79
+ } else if (annotation.data.action === 'insert') {
80
+ if (!annotation.data.newText) {
81
+ console.error('Insert suggestion must have newText:', annotation)
82
+ return false
83
+ }
84
+ }
85
+ } else if (isBlockAdditionAnnotation(annotation)) {
86
+ if (!annotation.data.content || !annotation.data.reason) {
87
+ console.error('Block addition must have content and reason:', annotation)
88
+ return false
89
+ }
90
+ }
91
+
92
+ return true
93
+ }
94
+
95
+ /**
96
+ * Validates an array of annotations
97
+ *
98
+ * @param annotations - Array of annotations to validate
99
+ * @param documentLength - Total length of the document
100
+ * @returns Object with validation results
101
+ */
102
+ export function validateAnnotations(
103
+ annotations: Annotation[],
104
+ documentLength: number
105
+ ): {
106
+ valid: boolean
107
+ errors: string[]
108
+ validAnnotations: Annotation[]
109
+ invalidAnnotations: Annotation[]
110
+ } {
111
+ const errors: string[] = []
112
+ const validAnnotations: Annotation[] = []
113
+ const invalidAnnotations: Annotation[] = []
114
+
115
+ for (const annotation of annotations) {
116
+ if (validateAnnotation(annotation, documentLength)) {
117
+ validAnnotations.push(annotation)
118
+ } else {
119
+ invalidAnnotations.push(annotation)
120
+ errors.push(`Invalid annotation: ${annotation.id}`)
121
+ }
122
+ }
123
+
124
+ return {
125
+ valid: errors.length === 0,
126
+ errors,
127
+ validAnnotations,
128
+ invalidAnnotations,
129
+ }
130
+ }