@gmickel/gno 0.7.0 → 0.8.1

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 (209) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +90 -50
  3. package/THIRD_PARTY_NOTICES.md +22 -0
  4. package/assets/screenshots/webui-ask-answer.png +0 -0
  5. package/assets/screenshots/webui-collections.png +0 -0
  6. package/assets/screenshots/webui-editor.png +0 -0
  7. package/assets/screenshots/webui-home.png +0 -0
  8. package/assets/skill/SKILL.md +12 -12
  9. package/assets/skill/cli-reference.md +59 -57
  10. package/assets/skill/examples.md +8 -7
  11. package/assets/skill/mcp-reference.md +8 -4
  12. package/package.json +31 -24
  13. package/src/app/constants.ts +43 -42
  14. package/src/cli/colors.ts +1 -1
  15. package/src/cli/commands/ask.ts +44 -43
  16. package/src/cli/commands/cleanup.ts +9 -8
  17. package/src/cli/commands/collection/add.ts +12 -12
  18. package/src/cli/commands/collection/index.ts +4 -4
  19. package/src/cli/commands/collection/list.ts +26 -25
  20. package/src/cli/commands/collection/remove.ts +10 -10
  21. package/src/cli/commands/collection/rename.ts +10 -10
  22. package/src/cli/commands/context/add.ts +1 -1
  23. package/src/cli/commands/context/check.ts +17 -17
  24. package/src/cli/commands/context/index.ts +4 -4
  25. package/src/cli/commands/context/list.ts +11 -11
  26. package/src/cli/commands/context/rm.ts +1 -1
  27. package/src/cli/commands/doctor.ts +86 -84
  28. package/src/cli/commands/embed.ts +30 -28
  29. package/src/cli/commands/get.ts +27 -26
  30. package/src/cli/commands/index-cmd.ts +9 -9
  31. package/src/cli/commands/index.ts +16 -16
  32. package/src/cli/commands/init.ts +13 -12
  33. package/src/cli/commands/ls.ts +20 -19
  34. package/src/cli/commands/mcp/config.ts +30 -28
  35. package/src/cli/commands/mcp/index.ts +4 -4
  36. package/src/cli/commands/mcp/install.ts +17 -17
  37. package/src/cli/commands/mcp/paths.ts +133 -133
  38. package/src/cli/commands/mcp/status.ts +21 -21
  39. package/src/cli/commands/mcp/uninstall.ts +13 -13
  40. package/src/cli/commands/mcp.ts +2 -2
  41. package/src/cli/commands/models/clear.ts +12 -11
  42. package/src/cli/commands/models/index.ts +5 -5
  43. package/src/cli/commands/models/list.ts +31 -30
  44. package/src/cli/commands/models/path.ts +1 -1
  45. package/src/cli/commands/models/pull.ts +19 -18
  46. package/src/cli/commands/models/use.ts +4 -4
  47. package/src/cli/commands/multi-get.ts +38 -36
  48. package/src/cli/commands/query.ts +21 -20
  49. package/src/cli/commands/ref-parser.ts +10 -10
  50. package/src/cli/commands/reset.ts +40 -39
  51. package/src/cli/commands/search.ts +14 -13
  52. package/src/cli/commands/serve.ts +4 -4
  53. package/src/cli/commands/shared.ts +11 -10
  54. package/src/cli/commands/skill/index.ts +5 -5
  55. package/src/cli/commands/skill/install.ts +18 -17
  56. package/src/cli/commands/skill/paths-cmd.ts +11 -10
  57. package/src/cli/commands/skill/paths.ts +23 -23
  58. package/src/cli/commands/skill/show.ts +13 -12
  59. package/src/cli/commands/skill/uninstall.ts +16 -15
  60. package/src/cli/commands/status.ts +25 -24
  61. package/src/cli/commands/update.ts +3 -3
  62. package/src/cli/commands/vsearch.ts +17 -16
  63. package/src/cli/context.ts +5 -5
  64. package/src/cli/errors.ts +3 -3
  65. package/src/cli/format/search-results.ts +37 -37
  66. package/src/cli/options.ts +43 -43
  67. package/src/cli/program.ts +455 -459
  68. package/src/cli/progress.ts +1 -1
  69. package/src/cli/run.ts +24 -23
  70. package/src/collection/add.ts +9 -8
  71. package/src/collection/index.ts +3 -3
  72. package/src/collection/remove.ts +7 -6
  73. package/src/collection/types.ts +6 -6
  74. package/src/config/defaults.ts +1 -1
  75. package/src/config/index.ts +5 -5
  76. package/src/config/loader.ts +19 -18
  77. package/src/config/paths.ts +9 -8
  78. package/src/config/saver.ts +14 -13
  79. package/src/config/types.ts +53 -52
  80. package/src/converters/adapters/markitdownTs/adapter.ts +21 -19
  81. package/src/converters/adapters/officeparser/adapter.ts +18 -16
  82. package/src/converters/canonicalize.ts +12 -12
  83. package/src/converters/errors.ts +26 -22
  84. package/src/converters/index.ts +8 -8
  85. package/src/converters/mime.ts +25 -25
  86. package/src/converters/native/markdown.ts +10 -9
  87. package/src/converters/native/plaintext.ts +8 -7
  88. package/src/converters/path.ts +2 -2
  89. package/src/converters/pipeline.ts +11 -10
  90. package/src/converters/registry.ts +8 -8
  91. package/src/converters/types.ts +14 -14
  92. package/src/converters/versions.ts +4 -4
  93. package/src/index.ts +4 -4
  94. package/src/ingestion/chunker.ts +10 -9
  95. package/src/ingestion/index.ts +6 -6
  96. package/src/ingestion/language.ts +62 -62
  97. package/src/ingestion/sync.ts +50 -49
  98. package/src/ingestion/types.ts +10 -10
  99. package/src/ingestion/walker.ts +14 -13
  100. package/src/llm/cache.ts +51 -49
  101. package/src/llm/errors.ts +40 -36
  102. package/src/llm/index.ts +9 -9
  103. package/src/llm/lockfile.ts +6 -6
  104. package/src/llm/nodeLlamaCpp/adapter.ts +13 -12
  105. package/src/llm/nodeLlamaCpp/embedding.ts +9 -8
  106. package/src/llm/nodeLlamaCpp/generation.ts +7 -6
  107. package/src/llm/nodeLlamaCpp/lifecycle.ts +11 -10
  108. package/src/llm/nodeLlamaCpp/rerank.ts +6 -5
  109. package/src/llm/policy.ts +5 -5
  110. package/src/llm/registry.ts +6 -5
  111. package/src/llm/types.ts +2 -2
  112. package/src/mcp/resources/index.ts +15 -13
  113. package/src/mcp/server.ts +25 -23
  114. package/src/mcp/tools/get.ts +25 -23
  115. package/src/mcp/tools/index.ts +32 -29
  116. package/src/mcp/tools/multi-get.ts +34 -32
  117. package/src/mcp/tools/query.ts +29 -27
  118. package/src/mcp/tools/search.ts +14 -12
  119. package/src/mcp/tools/status.ts +12 -11
  120. package/src/mcp/tools/vsearch.ts +26 -24
  121. package/src/pipeline/answer.ts +9 -9
  122. package/src/pipeline/chunk-lookup.ts +1 -1
  123. package/src/pipeline/contextual.ts +4 -4
  124. package/src/pipeline/expansion.ts +23 -21
  125. package/src/pipeline/explain.ts +21 -21
  126. package/src/pipeline/fusion.ts +9 -9
  127. package/src/pipeline/hybrid.ts +41 -42
  128. package/src/pipeline/index.ts +10 -10
  129. package/src/pipeline/query-language.ts +39 -39
  130. package/src/pipeline/rerank.ts +8 -7
  131. package/src/pipeline/search.ts +22 -22
  132. package/src/pipeline/types.ts +8 -8
  133. package/src/pipeline/vsearch.ts +21 -24
  134. package/src/serve/CLAUDE.md +21 -15
  135. package/src/serve/config-sync.ts +9 -8
  136. package/src/serve/context.ts +19 -18
  137. package/src/serve/index.ts +1 -1
  138. package/src/serve/jobs.ts +7 -7
  139. package/src/serve/public/app.tsx +79 -25
  140. package/src/serve/public/components/AddCollectionDialog.tsx +382 -0
  141. package/src/serve/public/components/CaptureButton.tsx +60 -0
  142. package/src/serve/public/components/CaptureModal.tsx +365 -0
  143. package/src/serve/public/components/IndexingProgress.tsx +333 -0
  144. package/src/serve/public/components/ShortcutHelpModal.tsx +106 -0
  145. package/src/serve/public/components/ai-elements/code-block.tsx +42 -32
  146. package/src/serve/public/components/ai-elements/conversation.tsx +16 -14
  147. package/src/serve/public/components/ai-elements/inline-citation.tsx +33 -32
  148. package/src/serve/public/components/ai-elements/loader.tsx +5 -4
  149. package/src/serve/public/components/ai-elements/message.tsx +39 -37
  150. package/src/serve/public/components/ai-elements/prompt-input.tsx +97 -95
  151. package/src/serve/public/components/ai-elements/sources.tsx +12 -10
  152. package/src/serve/public/components/ai-elements/suggestion.tsx +10 -9
  153. package/src/serve/public/components/editor/CodeMirrorEditor.tsx +142 -0
  154. package/src/serve/public/components/editor/MarkdownPreview.tsx +311 -0
  155. package/src/serve/public/components/editor/index.ts +6 -0
  156. package/src/serve/public/components/preset-selector.tsx +29 -28
  157. package/src/serve/public/components/ui/badge.tsx +13 -12
  158. package/src/serve/public/components/ui/button-group.tsx +13 -12
  159. package/src/serve/public/components/ui/button.tsx +23 -22
  160. package/src/serve/public/components/ui/card.tsx +16 -16
  161. package/src/serve/public/components/ui/carousel.tsx +36 -35
  162. package/src/serve/public/components/ui/collapsible.tsx +1 -1
  163. package/src/serve/public/components/ui/command.tsx +17 -15
  164. package/src/serve/public/components/ui/dialog.tsx +13 -12
  165. package/src/serve/public/components/ui/dropdown-menu.tsx +13 -12
  166. package/src/serve/public/components/ui/hover-card.tsx +6 -5
  167. package/src/serve/public/components/ui/input-group.tsx +45 -43
  168. package/src/serve/public/components/ui/input.tsx +6 -6
  169. package/src/serve/public/components/ui/progress.tsx +5 -4
  170. package/src/serve/public/components/ui/scroll-area.tsx +11 -10
  171. package/src/serve/public/components/ui/select.tsx +19 -18
  172. package/src/serve/public/components/ui/separator.tsx +6 -5
  173. package/src/serve/public/components/ui/table.tsx +18 -18
  174. package/src/serve/public/components/ui/textarea.tsx +4 -4
  175. package/src/serve/public/components/ui/tooltip.tsx +5 -4
  176. package/src/serve/public/globals.css +27 -4
  177. package/src/serve/public/hooks/use-api.ts +8 -8
  178. package/src/serve/public/hooks/useCaptureModal.tsx +83 -0
  179. package/src/serve/public/hooks/useKeyboardShortcuts.ts +85 -0
  180. package/src/serve/public/index.html +4 -4
  181. package/src/serve/public/lib/utils.ts +6 -0
  182. package/src/serve/public/pages/Ask.tsx +27 -26
  183. package/src/serve/public/pages/Browse.tsx +28 -27
  184. package/src/serve/public/pages/Collections.tsx +439 -0
  185. package/src/serve/public/pages/Dashboard.tsx +166 -40
  186. package/src/serve/public/pages/DocView.tsx +258 -73
  187. package/src/serve/public/pages/DocumentEditor.tsx +510 -0
  188. package/src/serve/public/pages/Search.tsx +80 -58
  189. package/src/serve/routes/api.ts +272 -155
  190. package/src/serve/security.ts +4 -4
  191. package/src/serve/server.ts +66 -48
  192. package/src/store/index.ts +5 -5
  193. package/src/store/migrations/001-initial.ts +24 -23
  194. package/src/store/migrations/002-documents-fts.ts +7 -6
  195. package/src/store/migrations/index.ts +4 -4
  196. package/src/store/migrations/runner.ts +17 -15
  197. package/src/store/sqlite/adapter.ts +123 -121
  198. package/src/store/sqlite/fts5-snowball.ts +24 -23
  199. package/src/store/sqlite/index.ts +1 -1
  200. package/src/store/sqlite/setup.ts +12 -12
  201. package/src/store/sqlite/types.ts +4 -4
  202. package/src/store/types.ts +19 -19
  203. package/src/store/vector/index.ts +3 -3
  204. package/src/store/vector/sqlite-vec.ts +23 -20
  205. package/src/store/vector/stats.ts +10 -8
  206. package/src/store/vector/types.ts +2 -2
  207. package/vendor/fts5-snowball/README.md +6 -6
  208. package/assets/screenshots/webui-ask-answer.jpg +0 -0
  209. package/assets/screenshots/webui-home.jpg +0 -0
@@ -0,0 +1,106 @@
1
+ /**
2
+ * ShortcutHelpModal - Displays available keyboard shortcuts.
3
+ *
4
+ * Features:
5
+ * - Grouped by context (Global, Editor, Navigation)
6
+ * - Platform-appropriate modifier display
7
+ * - Triggered by Cmd+/ or help button
8
+ */
9
+
10
+ import { KeyboardIcon } from "lucide-react";
11
+
12
+ import { modKey } from "../hooks/useKeyboardShortcuts";
13
+ import { Dialog, DialogContent, DialogHeader, DialogTitle } from "./ui/dialog";
14
+
15
+ export interface ShortcutHelpModalProps {
16
+ open: boolean;
17
+ onOpenChange: (open: boolean) => void;
18
+ }
19
+
20
+ interface ShortcutItem {
21
+ keys: string;
22
+ description: string;
23
+ }
24
+
25
+ interface ShortcutGroup {
26
+ title: string;
27
+ shortcuts: ShortcutItem[];
28
+ }
29
+
30
+ const shortcutGroups: ShortcutGroup[] = [
31
+ {
32
+ title: "Global",
33
+ shortcuts: [
34
+ { keys: `${modKey}+N`, description: "New note" },
35
+ { keys: `${modKey}+K`, description: "Focus search" },
36
+ { keys: `${modKey}+/`, description: "Show shortcuts" },
37
+ { keys: "Esc", description: "Close modal" },
38
+ ],
39
+ },
40
+ {
41
+ title: "Editor",
42
+ shortcuts: [
43
+ { keys: `${modKey}+S`, description: "Save" },
44
+ { keys: `${modKey}+B`, description: "Bold" },
45
+ { keys: `${modKey}+I`, description: "Italic" },
46
+ { keys: `${modKey}+K`, description: "Insert link" },
47
+ { keys: "Esc", description: "Close editor" },
48
+ ],
49
+ },
50
+ {
51
+ title: "Navigation",
52
+ shortcuts: [{ keys: `${modKey}+Enter`, description: "Submit form" }],
53
+ },
54
+ ];
55
+
56
+ export function ShortcutHelpModal({
57
+ open,
58
+ onOpenChange,
59
+ }: ShortcutHelpModalProps) {
60
+ return (
61
+ <Dialog onOpenChange={onOpenChange} open={open}>
62
+ <DialogContent className="max-w-md">
63
+ <DialogHeader>
64
+ <DialogTitle className="flex items-center gap-2">
65
+ <KeyboardIcon className="size-5" />
66
+ Keyboard Shortcuts
67
+ </DialogTitle>
68
+ </DialogHeader>
69
+
70
+ <div className="space-y-6">
71
+ {shortcutGroups.map((group) => (
72
+ <div key={group.title}>
73
+ <h3 className="mb-3 font-medium text-muted-foreground text-xs uppercase tracking-wider">
74
+ {group.title}
75
+ </h3>
76
+ <div className="space-y-2.5">
77
+ {group.shortcuts.map((shortcut) => (
78
+ <div
79
+ className="flex items-center justify-between rounded-md px-2 py-1.5 transition-colors hover:bg-muted/50"
80
+ key={shortcut.keys}
81
+ >
82
+ <span className="text-sm">{shortcut.description}</span>
83
+ <div className="flex items-center gap-1">
84
+ {shortcut.keys.split("+").map((key, i) => (
85
+ <span key={key}>
86
+ {i > 0 && (
87
+ <span className="mx-0.5 text-muted-foreground/50">
88
+ +
89
+ </span>
90
+ )}
91
+ <kbd className="inline-flex min-w-[1.75rem] items-center justify-center rounded border border-border/80 bg-gradient-to-b from-muted/80 to-muted px-1.5 py-0.5 font-mono text-[11px] text-foreground shadow-[0_2px_0_hsl(var(--border)),inset_0_1px_0_hsl(var(--background)/0.5)]">
92
+ {key}
93
+ </kbd>
94
+ </span>
95
+ ))}
96
+ </div>
97
+ </div>
98
+ ))}
99
+ </div>
100
+ </div>
101
+ ))}
102
+ </div>
103
+ </DialogContent>
104
+ </Dialog>
105
+ );
106
+ }
@@ -1,4 +1,4 @@
1
- import { CheckIcon, CopyIcon } from 'lucide-react';
1
+ import { CheckIcon, CopyIcon } from "lucide-react";
2
2
  import {
3
3
  type ComponentProps,
4
4
  createContext,
@@ -7,10 +7,11 @@ import {
7
7
  useEffect,
8
8
  useRef,
9
9
  useState,
10
- } from 'react';
11
- import { type BundledLanguage, codeToHtml, type ShikiTransformer } from 'shiki';
12
- import { cn } from '../../lib/utils';
13
- import { Button } from '../ui/button';
10
+ } from "react";
11
+ import { type BundledLanguage, codeToHtml, type ShikiTransformer } from "shiki";
12
+
13
+ import { cn } from "../../lib/utils";
14
+ import { Button } from "../ui/button";
14
15
 
15
16
  type CodeBlockProps = HTMLAttributes<HTMLDivElement> & {
16
17
  code: string;
@@ -23,26 +24,26 @@ interface CodeBlockContextType {
23
24
  }
24
25
 
25
26
  const CodeBlockContext = createContext<CodeBlockContextType>({
26
- code: '',
27
+ code: "",
27
28
  });
28
29
 
29
30
  const lineNumberTransformer: ShikiTransformer = {
30
- name: 'line-numbers',
31
+ name: "line-numbers",
31
32
  line(node, line) {
32
33
  node.children.unshift({
33
- type: 'element',
34
- tagName: 'span',
34
+ type: "element",
35
+ tagName: "span",
35
36
  properties: {
36
37
  className: [
37
- 'inline-block',
38
- 'min-w-10',
39
- 'mr-4',
40
- 'text-right',
41
- 'select-none',
42
- 'text-muted-foreground',
38
+ "inline-block",
39
+ "min-w-10",
40
+ "mr-4",
41
+ "text-right",
42
+ "select-none",
43
+ "text-muted-foreground",
43
44
  ],
44
45
  },
45
- children: [{ type: 'text', value: String(line) }],
46
+ children: [{ type: "text", value: String(line) }],
46
47
  });
47
48
  },
48
49
  };
@@ -59,12 +60,12 @@ export async function highlightCode(
59
60
  return await Promise.all([
60
61
  codeToHtml(code, {
61
62
  lang: language,
62
- theme: 'one-light',
63
+ theme: "one-light",
63
64
  transformers,
64
65
  }),
65
66
  codeToHtml(code, {
66
67
  lang: language,
67
- theme: 'one-dark-pro',
68
+ theme: "one-dark-pro",
68
69
  transformers,
69
70
  }),
70
71
  ]);
@@ -78,21 +79,30 @@ export const CodeBlock = ({
78
79
  children,
79
80
  ...props
80
81
  }: CodeBlockProps) => {
81
- const [html, setHtml] = useState<string>('');
82
- const [darkHtml, setDarkHtml] = useState<string>('');
83
- const mounted = useRef(false);
82
+ const [html, setHtml] = useState<string>("");
83
+ const [darkHtml, setDarkHtml] = useState<string>("");
84
+ const requestIdRef = useRef(0);
84
85
 
85
86
  useEffect(() => {
86
- highlightCode(code, language, showLineNumbers).then(([light, dark]) => {
87
- if (!mounted.current) {
87
+ let cancelled = false;
88
+ const requestId = ++requestIdRef.current;
89
+
90
+ async function highlight() {
91
+ const [light, dark] = await highlightCode(
92
+ code,
93
+ language,
94
+ showLineNumbers
95
+ );
96
+ // Only apply if this is still the latest request AND not cancelled
97
+ if (!cancelled && requestId === requestIdRef.current) {
88
98
  setHtml(light);
89
99
  setDarkHtml(dark);
90
- mounted.current = true;
91
100
  }
92
- });
101
+ }
93
102
 
103
+ void highlight();
94
104
  return () => {
95
- mounted.current = false;
105
+ cancelled = true;
96
106
  };
97
107
  }, [code, language, showLineNumbers]);
98
108
 
@@ -100,7 +110,7 @@ export const CodeBlock = ({
100
110
  <CodeBlockContext.Provider value={{ code }}>
101
111
  <div
102
112
  className={cn(
103
- 'group relative w-full overflow-hidden rounded-md border bg-background text-foreground',
113
+ "group relative w-full overflow-hidden rounded-md border bg-background text-foreground",
104
114
  className
105
115
  )}
106
116
  {...props}
@@ -108,12 +118,12 @@ export const CodeBlock = ({
108
118
  <div className="relative">
109
119
  <div
110
120
  className="overflow-auto dark:hidden [&>pre]:m-0 [&>pre]:bg-background! [&>pre]:p-4 [&>pre]:text-foreground! [&>pre]:text-sm [&_code]:font-mono [&_code]:text-sm"
111
- // biome-ignore lint/security/noDangerouslySetInnerHtml: "this is needed."
121
+ // oxlint-disable-next-line react/no-danger -- syntax highlighting requires innerHTML
112
122
  dangerouslySetInnerHTML={{ __html: html }}
113
123
  />
114
124
  <div
115
125
  className="hidden overflow-auto dark:block [&>pre]:m-0 [&>pre]:bg-background! [&>pre]:p-4 [&>pre]:text-foreground! [&>pre]:text-sm [&_code]:font-mono [&_code]:text-sm"
116
- // biome-ignore lint/security/noDangerouslySetInnerHtml: "this is needed."
126
+ // oxlint-disable-next-line react/no-danger -- syntax highlighting requires innerHTML
117
127
  dangerouslySetInnerHTML={{ __html: darkHtml }}
118
128
  />
119
129
  {children && (
@@ -145,8 +155,8 @@ export const CodeBlockCopyButton = ({
145
155
  const { code } = useContext(CodeBlockContext);
146
156
 
147
157
  const copyToClipboard = async () => {
148
- if (typeof window === 'undefined' || !navigator?.clipboard?.writeText) {
149
- onError?.(new Error('Clipboard API not available'));
158
+ if (typeof window === "undefined" || !navigator?.clipboard?.writeText) {
159
+ onError?.(new Error("Clipboard API not available"));
150
160
  return;
151
161
  }
152
162
 
@@ -164,7 +174,7 @@ export const CodeBlockCopyButton = ({
164
174
 
165
175
  return (
166
176
  <Button
167
- className={cn('shrink-0', className)}
177
+ className={cn("shrink-0", className)}
168
178
  onClick={copyToClipboard}
169
179
  size="icon"
170
180
  variant="ghost"
@@ -1,15 +1,17 @@
1
- import { ArrowDownIcon } from 'lucide-react';
2
- import type { ComponentProps } from 'react';
3
- import { useCallback } from 'react';
4
- import { StickToBottom, useStickToBottomContext } from 'use-stick-to-bottom';
5
- import { cn } from '../../lib/utils';
6
- import { Button } from '../ui/button';
1
+ import type { ComponentProps } from "react";
2
+
3
+ import { ArrowDownIcon } from "lucide-react";
4
+ import { useCallback } from "react";
5
+ import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
6
+
7
+ import { cn } from "../../lib/utils";
8
+ import { Button } from "../ui/button";
7
9
 
8
10
  export type ConversationProps = ComponentProps<typeof StickToBottom>;
9
11
 
10
12
  export const Conversation = ({ className, ...props }: ConversationProps) => (
11
13
  <StickToBottom
12
- className={cn('relative flex-1 overflow-y-hidden', className)}
14
+ className={cn("relative flex-1 overflow-y-hidden", className)}
13
15
  initial="smooth"
14
16
  resize="smooth"
15
17
  role="log"
@@ -26,12 +28,12 @@ export const ConversationContent = ({
26
28
  ...props
27
29
  }: ConversationContentProps) => (
28
30
  <StickToBottom.Content
29
- className={cn('flex flex-col gap-8 p-4', className)}
31
+ className={cn("flex flex-col gap-8 p-4", className)}
30
32
  {...props}
31
33
  />
32
34
  );
33
35
 
34
- export type ConversationEmptyStateProps = ComponentProps<'div'> & {
36
+ export type ConversationEmptyStateProps = ComponentProps<"div"> & {
35
37
  title?: string;
36
38
  description?: string;
37
39
  icon?: React.ReactNode;
@@ -39,15 +41,15 @@ export type ConversationEmptyStateProps = ComponentProps<'div'> & {
39
41
 
40
42
  export const ConversationEmptyState = ({
41
43
  className,
42
- title = 'No messages yet',
43
- description = 'Start a conversation to see messages here',
44
+ title = "No messages yet",
45
+ description = "Start a conversation to see messages here",
44
46
  icon,
45
47
  children,
46
48
  ...props
47
49
  }: ConversationEmptyStateProps) => (
48
50
  <div
49
51
  className={cn(
50
- 'flex size-full flex-col items-center justify-center gap-3 p-8 text-center',
52
+ "flex size-full flex-col items-center justify-center gap-3 p-8 text-center",
51
53
  className
52
54
  )}
53
55
  {...props}
@@ -75,14 +77,14 @@ export const ConversationScrollButton = ({
75
77
  const { isAtBottom, scrollToBottom } = useStickToBottomContext();
76
78
 
77
79
  const handleScrollToBottom = useCallback(() => {
78
- scrollToBottom();
80
+ void scrollToBottom();
79
81
  }, [scrollToBottom]);
80
82
 
81
83
  return (
82
84
  !isAtBottom && (
83
85
  <Button
84
86
  className={cn(
85
- 'absolute bottom-4 left-[50%] translate-x-[-50%] rounded-full',
87
+ "absolute bottom-4 left-[50%] translate-x-[-50%] rounded-full",
86
88
  className
87
89
  )}
88
90
  onClick={handleScrollToBottom}
@@ -1,4 +1,4 @@
1
- import { ArrowLeftIcon, ArrowRightIcon } from 'lucide-react';
1
+ import { ArrowLeftIcon, ArrowRightIcon } from "lucide-react";
2
2
  import {
3
3
  type ComponentProps,
4
4
  createContext,
@@ -6,41 +6,42 @@ import {
6
6
  useContext,
7
7
  useEffect,
8
8
  useState,
9
- } from 'react';
10
- import { cn } from '../../lib/utils';
11
- import { Badge } from '../ui/badge';
9
+ } from "react";
10
+
11
+ import { cn } from "../../lib/utils";
12
+ import { Badge } from "../ui/badge";
12
13
  import {
13
14
  Carousel,
14
15
  type CarouselApi,
15
16
  CarouselContent,
16
17
  CarouselItem,
17
- } from '../ui/carousel';
18
+ } from "../ui/carousel";
18
19
  import {
19
20
  HoverCard,
20
21
  HoverCardContent,
21
22
  HoverCardTrigger,
22
- } from '../ui/hover-card';
23
+ } from "../ui/hover-card";
23
24
 
24
- export type InlineCitationProps = ComponentProps<'span'>;
25
+ export type InlineCitationProps = ComponentProps<"span">;
25
26
 
26
27
  export const InlineCitation = ({
27
28
  className,
28
29
  ...props
29
30
  }: InlineCitationProps) => (
30
31
  <span
31
- className={cn('group inline items-center gap-1', className)}
32
+ className={cn("group inline items-center gap-1", className)}
32
33
  {...props}
33
34
  />
34
35
  );
35
36
 
36
- export type InlineCitationTextProps = ComponentProps<'span'>;
37
+ export type InlineCitationTextProps = ComponentProps<"span">;
37
38
 
38
39
  export const InlineCitationText = ({
39
40
  className,
40
41
  ...props
41
42
  }: InlineCitationTextProps) => (
42
43
  <span
43
- className={cn('transition-colors group-hover:bg-accent', className)}
44
+ className={cn("transition-colors group-hover:bg-accent", className)}
44
45
  {...props}
45
46
  />
46
47
  );
@@ -62,29 +63,29 @@ export const InlineCitationCardTrigger = ({
62
63
  }: InlineCitationCardTriggerProps) => (
63
64
  <HoverCardTrigger asChild>
64
65
  <Badge
65
- className={cn('ml-1 rounded-full', className)}
66
+ className={cn("ml-1 rounded-full", className)}
66
67
  variant="secondary"
67
68
  {...props}
68
69
  >
69
70
  {sources[0] ? (
70
71
  <>
71
- {new URL(sources[0]).hostname}{' '}
72
+ {new URL(sources[0]).hostname}{" "}
72
73
  {sources.length > 1 && `+${sources.length - 1}`}
73
74
  </>
74
75
  ) : (
75
- 'unknown'
76
+ "unknown"
76
77
  )}
77
78
  </Badge>
78
79
  </HoverCardTrigger>
79
80
  );
80
81
 
81
- export type InlineCitationCardBodyProps = ComponentProps<'div'>;
82
+ export type InlineCitationCardBodyProps = ComponentProps<"div">;
82
83
 
83
84
  export const InlineCitationCardBody = ({
84
85
  className,
85
86
  ...props
86
87
  }: InlineCitationCardBodyProps) => (
87
- <HoverCardContent className={cn('relative w-80 p-0', className)} {...props} />
88
+ <HoverCardContent className={cn("relative w-80 p-0", className)} {...props} />
88
89
  );
89
90
 
90
91
  const CarouselApiContext = createContext<CarouselApi | undefined>(undefined);
@@ -105,32 +106,32 @@ export const InlineCitationCarousel = ({
105
106
 
106
107
  return (
107
108
  <CarouselApiContext.Provider value={api}>
108
- <Carousel className={cn('w-full', className)} setApi={setApi} {...props}>
109
+ <Carousel className={cn("w-full", className)} setApi={setApi} {...props}>
109
110
  {children}
110
111
  </Carousel>
111
112
  </CarouselApiContext.Provider>
112
113
  );
113
114
  };
114
115
 
115
- export type InlineCitationCarouselContentProps = ComponentProps<'div'>;
116
+ export type InlineCitationCarouselContentProps = ComponentProps<"div">;
116
117
 
117
118
  export const InlineCitationCarouselContent = (
118
119
  props: InlineCitationCarouselContentProps
119
120
  ) => <CarouselContent {...props} />;
120
121
 
121
- export type InlineCitationCarouselItemProps = ComponentProps<'div'>;
122
+ export type InlineCitationCarouselItemProps = ComponentProps<"div">;
122
123
 
123
124
  export const InlineCitationCarouselItem = ({
124
125
  className,
125
126
  ...props
126
127
  }: InlineCitationCarouselItemProps) => (
127
128
  <CarouselItem
128
- className={cn('w-full space-y-2 p-4 pl-8', className)}
129
+ className={cn("w-full space-y-2 p-4 pl-8", className)}
129
130
  {...props}
130
131
  />
131
132
  );
132
133
 
133
- export type InlineCitationCarouselHeaderProps = ComponentProps<'div'>;
134
+ export type InlineCitationCarouselHeaderProps = ComponentProps<"div">;
134
135
 
135
136
  export const InlineCitationCarouselHeader = ({
136
137
  className,
@@ -138,14 +139,14 @@ export const InlineCitationCarouselHeader = ({
138
139
  }: InlineCitationCarouselHeaderProps) => (
139
140
  <div
140
141
  className={cn(
141
- 'flex items-center justify-between gap-2 rounded-t-md bg-secondary p-2',
142
+ "flex items-center justify-between gap-2 rounded-t-md bg-secondary p-2",
142
143
  className
143
144
  )}
144
145
  {...props}
145
146
  />
146
147
  );
147
148
 
148
- export type InlineCitationCarouselIndexProps = ComponentProps<'div'>;
149
+ export type InlineCitationCarouselIndexProps = ComponentProps<"div">;
149
150
 
150
151
  export const InlineCitationCarouselIndex = ({
151
152
  children,
@@ -164,7 +165,7 @@ export const InlineCitationCarouselIndex = ({
164
165
  setCount(api.scrollSnapList().length);
165
166
  setCurrent(api.selectedScrollSnap() + 1);
166
167
 
167
- api.on('select', () => {
168
+ api.on("select", () => {
168
169
  setCurrent(api.selectedScrollSnap() + 1);
169
170
  });
170
171
  }, [api]);
@@ -172,7 +173,7 @@ export const InlineCitationCarouselIndex = ({
172
173
  return (
173
174
  <div
174
175
  className={cn(
175
- 'flex flex-1 items-center justify-end px-3 py-1 text-muted-foreground text-xs',
176
+ "flex flex-1 items-center justify-end px-3 py-1 text-muted-foreground text-xs",
176
177
  className
177
178
  )}
178
179
  {...props}
@@ -182,7 +183,7 @@ export const InlineCitationCarouselIndex = ({
182
183
  );
183
184
  };
184
185
 
185
- export type InlineCitationCarouselPrevProps = ComponentProps<'button'>;
186
+ export type InlineCitationCarouselPrevProps = ComponentProps<"button">;
186
187
 
187
188
  export const InlineCitationCarouselPrev = ({
188
189
  className,
@@ -199,7 +200,7 @@ export const InlineCitationCarouselPrev = ({
199
200
  return (
200
201
  <button
201
202
  aria-label="Previous"
202
- className={cn('shrink-0', className)}
203
+ className={cn("shrink-0", className)}
203
204
  onClick={handleClick}
204
205
  type="button"
205
206
  {...props}
@@ -209,7 +210,7 @@ export const InlineCitationCarouselPrev = ({
209
210
  );
210
211
  };
211
212
 
212
- export type InlineCitationCarouselNextProps = ComponentProps<'button'>;
213
+ export type InlineCitationCarouselNextProps = ComponentProps<"button">;
213
214
 
214
215
  export const InlineCitationCarouselNext = ({
215
216
  className,
@@ -226,7 +227,7 @@ export const InlineCitationCarouselNext = ({
226
227
  return (
227
228
  <button
228
229
  aria-label="Next"
229
- className={cn('shrink-0', className)}
230
+ className={cn("shrink-0", className)}
230
231
  onClick={handleClick}
231
232
  type="button"
232
233
  {...props}
@@ -236,7 +237,7 @@ export const InlineCitationCarouselNext = ({
236
237
  );
237
238
  };
238
239
 
239
- export type InlineCitationSourceProps = ComponentProps<'div'> & {
240
+ export type InlineCitationSourceProps = ComponentProps<"div"> & {
240
241
  title?: string;
241
242
  url?: string;
242
243
  description?: string;
@@ -250,7 +251,7 @@ export const InlineCitationSource = ({
250
251
  children,
251
252
  ...props
252
253
  }: InlineCitationSourceProps) => (
253
- <div className={cn('space-y-1', className)} {...props}>
254
+ <div className={cn("space-y-1", className)} {...props}>
254
255
  {title && (
255
256
  <h4 className="truncate font-medium text-sm leading-tight">{title}</h4>
256
257
  )}
@@ -266,7 +267,7 @@ export const InlineCitationSource = ({
266
267
  </div>
267
268
  );
268
269
 
269
- export type InlineCitationQuoteProps = ComponentProps<'blockquote'>;
270
+ export type InlineCitationQuoteProps = ComponentProps<"blockquote">;
270
271
 
271
272
  export const InlineCitationQuote = ({
272
273
  children,
@@ -275,7 +276,7 @@ export const InlineCitationQuote = ({
275
276
  }: InlineCitationQuoteProps) => (
276
277
  <blockquote
277
278
  className={cn(
278
- 'border-muted border-l-2 pl-3 text-muted-foreground text-sm italic',
279
+ "border-muted border-l-2 pl-3 text-muted-foreground text-sm italic",
279
280
  className
280
281
  )}
281
282
  {...props}
@@ -1,5 +1,6 @@
1
- import type { HTMLAttributes } from 'react';
2
- import { cn } from '../../lib/utils';
1
+ import type { HTMLAttributes } from "react";
2
+
3
+ import { cn } from "../../lib/utils";
3
4
 
4
5
  interface LoaderIconProps {
5
6
  size?: number;
@@ -9,7 +10,7 @@ const LoaderIcon = ({ size = 16 }: LoaderIconProps) => (
9
10
  <svg
10
11
  height={size}
11
12
  strokeLinejoin="round"
12
- style={{ color: 'currentcolor' }}
13
+ style={{ color: "currentcolor" }}
13
14
  viewBox="0 0 16 16"
14
15
  width={size}
15
16
  >
@@ -86,7 +87,7 @@ export type LoaderProps = HTMLAttributes<HTMLDivElement> & {
86
87
  export const Loader = ({ className, size = 16, ...props }: LoaderProps) => (
87
88
  <div
88
89
  className={cn(
89
- 'inline-flex animate-spin items-center justify-center',
90
+ "inline-flex animate-spin items-center justify-center",
90
91
  className
91
92
  )}
92
93
  {...props}