@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
@@ -5,10 +5,11 @@ import {
5
5
  Download,
6
6
  Loader2,
7
7
  SlidersHorizontal,
8
- } from 'lucide-react';
9
- import { useCallback, useEffect, useRef, useState } from 'react';
10
- import { apiFetch } from '../hooks/use-api';
11
- import { Button } from './ui/button';
8
+ } from "lucide-react";
9
+ import { useCallback, useEffect, useRef, useState } from "react";
10
+
11
+ import { apiFetch } from "../hooks/use-api";
12
+ import { Button } from "./ui/button";
12
13
  import {
13
14
  DropdownMenu,
14
15
  DropdownMenuContent,
@@ -17,8 +18,8 @@ import {
17
18
  DropdownMenuRadioItem,
18
19
  DropdownMenuSeparator,
19
20
  DropdownMenuTrigger,
20
- } from './ui/dropdown-menu';
21
- import { Progress } from './ui/progress';
21
+ } from "./ui/dropdown-menu";
22
+ import { Progress } from "./ui/progress";
22
23
 
23
24
  interface Preset {
24
25
  id: string;
@@ -82,7 +83,7 @@ function extractDesc(name: string): string | null {
82
83
  }
83
84
 
84
85
  function extractBaseName(name: string): string {
85
- return name.split('(')[0].trim();
86
+ return name.split("(")[0].trim();
86
87
  }
87
88
 
88
89
  function formatBytes(bytes: number): string {
@@ -123,17 +124,17 @@ function getButtonLabel(
123
124
  activePreset: Preset | undefined
124
125
  ): string {
125
126
  if (switching) {
126
- return 'Switching...';
127
+ return "Switching...";
127
128
  }
128
129
  if (downloading) {
129
- return 'Downloading...';
130
+ return "Downloading...";
130
131
  }
131
- return activePreset ? extractBaseName(activePreset.name) : 'Preset';
132
+ return activePreset ? extractBaseName(activePreset.name) : "Preset";
132
133
  }
133
134
 
134
135
  export function PresetSelector() {
135
136
  const [presets, setPresets] = useState<Preset[]>([]);
136
- const [activeId, setActiveId] = useState<string>('');
137
+ const [activeId, setActiveId] = useState<string>("");
137
138
  const [loading, setLoading] = useState(true);
138
139
  const [switching, setSwitching] = useState(false);
139
140
  const [error, setError] = useState<string | null>(null);
@@ -150,14 +151,14 @@ export function PresetSelector() {
150
151
  const checkCapabilities = useCallback((caps: Capabilities) => {
151
152
  const missing: string[] = [];
152
153
  if (!caps.vector) {
153
- missing.push('vector search');
154
+ missing.push("vector search");
154
155
  }
155
156
  if (!caps.answer) {
156
- missing.push('AI answers');
157
+ missing.push("AI answers");
157
158
  }
158
159
 
159
160
  if (missing.length > 0) {
160
- setError(`Missing: ${missing.join(', ')}`);
161
+ setError(`Missing: ${missing.join(", ")}`);
161
162
  setModelsNeeded(true);
162
163
  } else {
163
164
  setError(null);
@@ -167,7 +168,7 @@ export function PresetSelector() {
167
168
 
168
169
  // Poll download status
169
170
  const pollStatus = useCallback(async () => {
170
- const { data } = await apiFetch<DownloadStatus>('/api/models/status');
171
+ const { data } = await apiFetch<DownloadStatus>("/api/models/status");
171
172
  if (data) {
172
173
  setDownloadStatus(data);
173
174
 
@@ -181,14 +182,14 @@ export function PresetSelector() {
181
182
 
182
183
  // Refresh presets to get updated capabilities
183
184
  const { data: presetsData } =
184
- await apiFetch<PresetsResponse>('/api/presets');
185
+ await apiFetch<PresetsResponse>("/api/presets");
185
186
  if (presetsData) {
186
187
  checkCapabilities(presetsData.capabilities);
187
188
  }
188
189
 
189
190
  // Show any failures
190
191
  if (data.failed.length > 0) {
191
- setError(`Failed: ${data.failed.map((f) => f.type).join(', ')}`);
192
+ setError(`Failed: ${data.failed.map((f) => f.type).join(", ")}`);
192
193
  }
193
194
  }
194
195
  }
@@ -196,7 +197,7 @@ export function PresetSelector() {
196
197
 
197
198
  // Initial load
198
199
  useEffect(() => {
199
- apiFetch<PresetsResponse>('/api/presets').then(({ data }) => {
200
+ void apiFetch<PresetsResponse>("/api/presets").then(({ data }) => {
200
201
  if (data) {
201
202
  setPresets(data.presets);
202
203
  setActiveId(data.activePreset);
@@ -206,7 +207,7 @@ export function PresetSelector() {
206
207
  });
207
208
 
208
209
  // Check if download already in progress
209
- apiFetch<DownloadStatus>('/api/models/status').then(({ data }) => {
210
+ void apiFetch<DownloadStatus>("/api/models/status").then(({ data }) => {
210
211
  if (data?.active) {
211
212
  setDownloading(true);
212
213
  setDownloadStatus(data);
@@ -242,10 +243,10 @@ export function PresetSelector() {
242
243
  setError(null);
243
244
 
244
245
  const { data, error: fetchError } = await apiFetch<SetPresetResponse>(
245
- '/api/presets',
246
+ "/api/presets",
246
247
  {
247
- method: 'POST',
248
- headers: { 'Content-Type': 'application/json' },
248
+ method: "POST",
249
+ headers: { "Content-Type": "application/json" },
249
250
  body: JSON.stringify({ presetId: id }),
250
251
  }
251
252
  );
@@ -271,8 +272,8 @@ export function PresetSelector() {
271
272
  setDownloading(true);
272
273
  setError(null);
273
274
 
274
- const { error: fetchError } = await apiFetch('/api/models/pull', {
275
- method: 'POST',
275
+ const { error: fetchError } = await apiFetch("/api/models/pull", {
276
+ method: "POST",
276
277
  });
277
278
 
278
279
  if (fetchError) {
@@ -282,7 +283,7 @@ export function PresetSelector() {
282
283
  }
283
284
 
284
285
  // Start polling
285
- pollStatus();
286
+ void pollStatus();
286
287
  };
287
288
 
288
289
  return (
@@ -317,11 +318,11 @@ export function PresetSelector() {
317
318
  <div className="space-y-2 px-2 py-2">
318
319
  <div className="flex items-center justify-between text-xs">
319
320
  <span className="text-muted-foreground">
320
- {downloadStatus.currentType || 'Starting...'}
321
+ {downloadStatus.currentType || "Starting..."}
321
322
  </span>
322
323
  {downloadStatus.progress && (
323
324
  <span className="font-mono text-[10px] text-muted-foreground">
324
- {formatBytes(downloadStatus.progress.downloadedBytes)} /{' '}
325
+ {formatBytes(downloadStatus.progress.downloadedBytes)} /{" "}
325
326
  {formatBytes(downloadStatus.progress.totalBytes)}
326
327
  </span>
327
328
  )}
@@ -329,7 +330,7 @@ export function PresetSelector() {
329
330
  <Progress value={downloadStatus.progress?.percent ?? 0} />
330
331
  {downloadStatus.completed.length > 0 && (
331
332
  <div className="text-[10px] text-muted-foreground">
332
- Done: {downloadStatus.completed.join(', ')}
333
+ Done: {downloadStatus.completed.join(", ")}
333
334
  </div>
334
335
  )}
335
336
  </div>
@@ -1,26 +1,27 @@
1
- import { Slot } from '@radix-ui/react-slot';
2
- import { cva, type VariantProps } from 'class-variance-authority';
3
- import type * as React from 'react';
1
+ import type * as React from "react";
4
2
 
5
- import { cn } from '../../lib/utils';
3
+ import { Slot } from "@radix-ui/react-slot";
4
+ import { cva, type VariantProps } from "class-variance-authority";
5
+
6
+ import { cn } from "../../lib/utils";
6
7
 
7
8
  const badgeVariants = cva(
8
- 'inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden whitespace-nowrap rounded-full border px-2 py-0.5 font-medium text-xs transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3',
9
+ "inline-flex w-fit shrink-0 items-center justify-center gap-1 overflow-hidden whitespace-nowrap rounded-full border px-2 py-0.5 font-medium text-xs transition-[color,box-shadow] focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3",
9
10
  {
10
11
  variants: {
11
12
  variant: {
12
13
  default:
13
- 'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
14
+ "border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90",
14
15
  secondary:
15
- 'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
16
+ "border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90",
16
17
  destructive:
17
- 'border-transparent bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90',
18
+ "border-transparent bg-destructive text-white focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40 [a&]:hover:bg-destructive/90",
18
19
  outline:
19
- 'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
20
+ "text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground",
20
21
  },
21
22
  },
22
23
  defaultVariants: {
23
- variant: 'default',
24
+ variant: "default",
24
25
  },
25
26
  }
26
27
  );
@@ -30,9 +31,9 @@ function Badge({
30
31
  variant,
31
32
  asChild = false,
32
33
  ...props
33
- }: React.ComponentProps<'span'> &
34
+ }: React.ComponentProps<"span"> &
34
35
  VariantProps<typeof badgeVariants> & { asChild?: boolean }) {
35
- const Comp = asChild ? Slot : 'span';
36
+ const Comp = asChild ? Slot : "span";
36
37
 
37
38
  return (
38
39
  <Comp
@@ -1,7 +1,8 @@
1
- import { Slot } from '@radix-ui/react-slot';
2
- import { cva, type VariantProps } from 'class-variance-authority';
3
- import { cn } from '../../lib/utils';
4
- import { Separator } from './separator';
1
+ import { Slot } from "@radix-ui/react-slot";
2
+ import { cva, type VariantProps } from "class-variance-authority";
3
+
4
+ import { cn } from "../../lib/utils";
5
+ import { Separator } from "./separator";
5
6
 
6
7
  const buttonGroupVariants = cva(
7
8
  "flex w-fit items-stretch has-[>[data-slot=button-group]]:gap-2 [&>*]:focus-visible:relative [&>*]:focus-visible:z-10 has-[select[aria-hidden=true]:last-child]:[&>[data-slot=select-trigger]:last-of-type]:rounded-r-md [&>[data-slot=select-trigger]:not([class*='w-'])]:w-fit [&>input]:flex-1",
@@ -9,13 +10,13 @@ const buttonGroupVariants = cva(
9
10
  variants: {
10
11
  orientation: {
11
12
  horizontal:
12
- '[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none',
13
+ "[&>*:not(:first-child)]:rounded-l-none [&>*:not(:first-child)]:border-l-0 [&>*:not(:last-child)]:rounded-r-none",
13
14
  vertical:
14
- 'flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none',
15
+ "flex-col [&>*:not(:first-child)]:rounded-t-none [&>*:not(:first-child)]:border-t-0 [&>*:not(:last-child)]:rounded-b-none",
15
16
  },
16
17
  },
17
18
  defaultVariants: {
18
- orientation: 'horizontal',
19
+ orientation: "horizontal",
19
20
  },
20
21
  }
21
22
  );
@@ -24,7 +25,7 @@ function ButtonGroup({
24
25
  className,
25
26
  orientation,
26
27
  ...props
27
- }: React.ComponentProps<'div'> & VariantProps<typeof buttonGroupVariants>) {
28
+ }: React.ComponentProps<"div"> & VariantProps<typeof buttonGroupVariants>) {
28
29
  return (
29
30
  <div
30
31
  className={cn(buttonGroupVariants({ orientation }), className)}
@@ -40,10 +41,10 @@ function ButtonGroupText({
40
41
  className,
41
42
  asChild = false,
42
43
  ...props
43
- }: React.ComponentProps<'div'> & {
44
+ }: React.ComponentProps<"div"> & {
44
45
  asChild?: boolean;
45
46
  }) {
46
- const Comp = asChild ? Slot : 'div';
47
+ const Comp = asChild ? Slot : "div";
47
48
 
48
49
  return (
49
50
  <Comp
@@ -58,13 +59,13 @@ function ButtonGroupText({
58
59
 
59
60
  function ButtonGroupSeparator({
60
61
  className,
61
- orientation = 'vertical',
62
+ orientation = "vertical",
62
63
  ...props
63
64
  }: React.ComponentProps<typeof Separator>) {
64
65
  return (
65
66
  <Separator
66
67
  className={cn(
67
- '!m-0 relative self-stretch bg-input data-[orientation=vertical]:h-auto',
68
+ "!m-0 relative self-stretch bg-input data-[orientation=vertical]:h-auto",
68
69
  className
69
70
  )}
70
71
  data-slot="button-group-separator"
@@ -1,52 +1,53 @@
1
- import { Slot } from '@radix-ui/react-slot';
2
- import { cva, type VariantProps } from 'class-variance-authority';
3
- import type * as React from 'react';
1
+ import type * as React from "react";
4
2
 
5
- import { cn } from '../../lib/utils';
3
+ import { Slot } from "@radix-ui/react-slot";
4
+ import { cva, type VariantProps } from "class-variance-authority";
5
+
6
+ import { cn } from "../../lib/utils";
6
7
 
7
8
  const buttonVariants = cva(
8
9
  "inline-flex shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md font-medium text-sm outline-none transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
9
10
  {
10
11
  variants: {
11
12
  variant: {
12
- default: 'bg-primary text-primary-foreground hover:bg-primary/90',
13
+ default: "bg-primary text-primary-foreground hover:bg-primary/90",
13
14
  destructive:
14
- 'bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40',
15
+ "bg-destructive text-white hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:bg-destructive/60 dark:focus-visible:ring-destructive/40",
15
16
  outline:
16
- 'border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50',
17
+ "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50",
17
18
  secondary:
18
- 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
19
+ "bg-secondary text-secondary-foreground hover:bg-secondary/80",
19
20
  ghost:
20
- 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
21
- link: 'text-primary underline-offset-4 hover:underline',
21
+ "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
22
+ link: "text-primary underline-offset-4 hover:underline",
22
23
  },
23
24
  size: {
24
- default: 'h-9 px-4 py-2 has-[>svg]:px-3',
25
- sm: 'h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5',
26
- lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
27
- icon: 'size-9',
28
- 'icon-sm': 'size-8',
29
- 'icon-lg': 'size-10',
25
+ default: "h-9 px-4 py-2 has-[>svg]:px-3",
26
+ sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
27
+ lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
28
+ icon: "size-9",
29
+ "icon-sm": "size-8",
30
+ "icon-lg": "size-10",
30
31
  },
31
32
  },
32
33
  defaultVariants: {
33
- variant: 'default',
34
- size: 'default',
34
+ variant: "default",
35
+ size: "default",
35
36
  },
36
37
  }
37
38
  );
38
39
 
39
40
  function Button({
40
41
  className,
41
- variant = 'default',
42
- size = 'default',
42
+ variant = "default",
43
+ size = "default",
43
44
  asChild = false,
44
45
  ...props
45
- }: React.ComponentProps<'button'> &
46
+ }: React.ComponentProps<"button"> &
46
47
  VariantProps<typeof buttonVariants> & {
47
48
  asChild?: boolean;
48
49
  }) {
49
- const Comp = asChild ? Slot : 'button';
50
+ const Comp = asChild ? Slot : "button";
50
51
 
51
52
  return (
52
53
  <Comp
@@ -1,12 +1,12 @@
1
- import type * as React from 'react';
1
+ import type * as React from "react";
2
2
 
3
- import { cn } from '../../lib/utils';
3
+ import { cn } from "../../lib/utils";
4
4
 
5
- function Card({ className, ...props }: React.ComponentProps<'div'>) {
5
+ function Card({ className, ...props }: React.ComponentProps<"div">) {
6
6
  return (
7
7
  <div
8
8
  className={cn(
9
- 'flex flex-col gap-6 rounded-xl border bg-card py-6 text-card-foreground shadow-sm',
9
+ "flex flex-col gap-6 rounded-xl border bg-card py-6 text-card-foreground shadow-sm",
10
10
  className
11
11
  )}
12
12
  data-slot="card"
@@ -15,11 +15,11 @@ function Card({ className, ...props }: React.ComponentProps<'div'>) {
15
15
  );
16
16
  }
17
17
 
18
- function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
18
+ function CardHeader({ className, ...props }: React.ComponentProps<"div">) {
19
19
  return (
20
20
  <div
21
21
  className={cn(
22
- '@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6',
22
+ "@container/card-header grid auto-rows-min grid-rows-[auto_auto] items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto] [.border-b]:pb-6",
23
23
  className
24
24
  )}
25
25
  data-slot="card-header"
@@ -28,31 +28,31 @@ function CardHeader({ className, ...props }: React.ComponentProps<'div'>) {
28
28
  );
29
29
  }
30
30
 
31
- function CardTitle({ className, ...props }: React.ComponentProps<'div'>) {
31
+ function CardTitle({ className, ...props }: React.ComponentProps<"div">) {
32
32
  return (
33
33
  <div
34
- className={cn('font-semibold leading-none', className)}
34
+ className={cn("font-semibold leading-none", className)}
35
35
  data-slot="card-title"
36
36
  {...props}
37
37
  />
38
38
  );
39
39
  }
40
40
 
41
- function CardDescription({ className, ...props }: React.ComponentProps<'div'>) {
41
+ function CardDescription({ className, ...props }: React.ComponentProps<"div">) {
42
42
  return (
43
43
  <div
44
- className={cn('text-muted-foreground text-sm', className)}
44
+ className={cn("text-muted-foreground text-sm", className)}
45
45
  data-slot="card-description"
46
46
  {...props}
47
47
  />
48
48
  );
49
49
  }
50
50
 
51
- function CardAction({ className, ...props }: React.ComponentProps<'div'>) {
51
+ function CardAction({ className, ...props }: React.ComponentProps<"div">) {
52
52
  return (
53
53
  <div
54
54
  className={cn(
55
- 'col-start-2 row-span-2 row-start-1 self-start justify-self-end',
55
+ "col-start-2 row-span-2 row-start-1 self-start justify-self-end",
56
56
  className
57
57
  )}
58
58
  data-slot="card-action"
@@ -61,20 +61,20 @@ function CardAction({ className, ...props }: React.ComponentProps<'div'>) {
61
61
  );
62
62
  }
63
63
 
64
- function CardContent({ className, ...props }: React.ComponentProps<'div'>) {
64
+ function CardContent({ className, ...props }: React.ComponentProps<"div">) {
65
65
  return (
66
66
  <div
67
- className={cn('px-6', className)}
67
+ className={cn("px-6", className)}
68
68
  data-slot="card-content"
69
69
  {...props}
70
70
  />
71
71
  );
72
72
  }
73
73
 
74
- function CardFooter({ className, ...props }: React.ComponentProps<'div'>) {
74
+ function CardFooter({ className, ...props }: React.ComponentProps<"div">) {
75
75
  return (
76
76
  <div
77
- className={cn('flex items-center px-6 [.border-t]:pt-6', className)}
77
+ className={cn("flex items-center px-6 [.border-t]:pt-6", className)}
78
78
  data-slot="card-footer"
79
79
  {...props}
80
80
  />
@@ -1,10 +1,11 @@
1
1
  import useEmblaCarousel, {
2
2
  type UseEmblaCarouselType,
3
- } from 'embla-carousel-react';
4
- import { ArrowLeft, ArrowRight } from 'lucide-react';
5
- import * as React from 'react';
6
- import { cn } from '../../lib/utils';
7
- import { Button } from './button';
3
+ } from "embla-carousel-react";
4
+ import { ArrowLeft, ArrowRight } from "lucide-react";
5
+ import * as React from "react";
6
+
7
+ import { cn } from "../../lib/utils";
8
+ import { Button } from "./button";
8
9
 
9
10
  type CarouselApi = UseEmblaCarouselType[1];
10
11
  type UseCarouselParameters = Parameters<typeof useEmblaCarousel>;
@@ -14,7 +15,7 @@ type CarouselPlugin = UseCarouselParameters[1];
14
15
  interface CarouselProps {
15
16
  opts?: CarouselOptions;
16
17
  plugins?: CarouselPlugin;
17
- orientation?: 'horizontal' | 'vertical';
18
+ orientation?: "horizontal" | "vertical";
18
19
  setApi?: (api: CarouselApi) => void;
19
20
  }
20
21
 
@@ -33,25 +34,25 @@ function useCarousel() {
33
34
  const context = React.useContext(CarouselContext);
34
35
 
35
36
  if (!context) {
36
- throw new Error('useCarousel must be used within a <Carousel />');
37
+ throw new Error("useCarousel must be used within a <Carousel />");
37
38
  }
38
39
 
39
40
  return context;
40
41
  }
41
42
 
42
43
  function Carousel({
43
- orientation = 'horizontal',
44
+ orientation = "horizontal",
44
45
  opts,
45
46
  setApi,
46
47
  plugins,
47
48
  className,
48
49
  children,
49
50
  ...props
50
- }: React.ComponentProps<'div'> & CarouselProps) {
51
+ }: React.ComponentProps<"div"> & CarouselProps) {
51
52
  const [carouselRef, api] = useEmblaCarousel(
52
53
  {
53
54
  ...opts,
54
- axis: orientation === 'horizontal' ? 'x' : 'y',
55
+ axis: orientation === "horizontal" ? "x" : "y",
55
56
  },
56
57
  plugins
57
58
  );
@@ -76,10 +77,10 @@ function Carousel({
76
77
 
77
78
  const handleKeyDown = React.useCallback(
78
79
  (event: React.KeyboardEvent<HTMLDivElement>) => {
79
- if (event.key === 'ArrowLeft') {
80
+ if (event.key === "ArrowLeft") {
80
81
  event.preventDefault();
81
82
  scrollPrev();
82
- } else if (event.key === 'ArrowRight') {
83
+ } else if (event.key === "ArrowRight") {
83
84
  event.preventDefault();
84
85
  scrollNext();
85
86
  }
@@ -99,11 +100,11 @@ function Carousel({
99
100
  return;
100
101
  }
101
102
  onSelect(api);
102
- api.on('reInit', onSelect);
103
- api.on('select', onSelect);
103
+ api.on("reInit", onSelect);
104
+ api.on("select", onSelect);
104
105
 
105
106
  return () => {
106
- api?.off('select', onSelect);
107
+ api?.off("select", onSelect);
107
108
  };
108
109
  }, [api, onSelect]);
109
110
 
@@ -114,7 +115,7 @@ function Carousel({
114
115
  api,
115
116
  opts,
116
117
  orientation:
117
- orientation || (opts?.axis === 'y' ? 'vertical' : 'horizontal'),
118
+ orientation || (opts?.axis === "y" ? "vertical" : "horizontal"),
118
119
  scrollPrev,
119
120
  scrollNext,
120
121
  canScrollPrev,
@@ -123,7 +124,7 @@ function Carousel({
123
124
  >
124
125
  <div
125
126
  aria-roledescription="carousel"
126
- className={cn('relative', className)}
127
+ className={cn("relative", className)}
127
128
  data-slot="carousel"
128
129
  onKeyDownCapture={handleKeyDown}
129
130
  role="region"
@@ -135,7 +136,7 @@ function Carousel({
135
136
  );
136
137
  }
137
138
 
138
- function CarouselContent({ className, ...props }: React.ComponentProps<'div'>) {
139
+ function CarouselContent({ className, ...props }: React.ComponentProps<"div">) {
139
140
  const { carouselRef, orientation } = useCarousel();
140
141
 
141
142
  return (
@@ -146,8 +147,8 @@ function CarouselContent({ className, ...props }: React.ComponentProps<'div'>) {
146
147
  >
147
148
  <div
148
149
  className={cn(
149
- 'flex',
150
- orientation === 'horizontal' ? '-ml-4' : '-mt-4 flex-col',
150
+ "flex",
151
+ orientation === "horizontal" ? "-ml-4" : "-mt-4 flex-col",
151
152
  className
152
153
  )}
153
154
  {...props}
@@ -156,15 +157,15 @@ function CarouselContent({ className, ...props }: React.ComponentProps<'div'>) {
156
157
  );
157
158
  }
158
159
 
159
- function CarouselItem({ className, ...props }: React.ComponentProps<'div'>) {
160
+ function CarouselItem({ className, ...props }: React.ComponentProps<"div">) {
160
161
  const { orientation } = useCarousel();
161
162
 
162
163
  return (
163
164
  <div
164
165
  aria-roledescription="slide"
165
166
  className={cn(
166
- 'min-w-0 shrink-0 grow-0 basis-full',
167
- orientation === 'horizontal' ? 'pl-4' : 'pt-4',
167
+ "min-w-0 shrink-0 grow-0 basis-full",
168
+ orientation === "horizontal" ? "pl-4" : "pt-4",
168
169
  className
169
170
  )}
170
171
  data-slot="carousel-item"
@@ -176,8 +177,8 @@ function CarouselItem({ className, ...props }: React.ComponentProps<'div'>) {
176
177
 
177
178
  function CarouselPrevious({
178
179
  className,
179
- variant = 'outline',
180
- size = 'icon',
180
+ variant = "outline",
181
+ size = "icon",
181
182
  ...props
182
183
  }: React.ComponentProps<typeof Button>) {
183
184
  const { orientation, scrollPrev, canScrollPrev } = useCarousel();
@@ -185,10 +186,10 @@ function CarouselPrevious({
185
186
  return (
186
187
  <Button
187
188
  className={cn(
188
- 'absolute size-8 rounded-full',
189
- orientation === 'horizontal'
190
- ? 'top-1/2 -left-12 -translate-y-1/2'
191
- : '-top-12 left-1/2 -translate-x-1/2 rotate-90',
189
+ "absolute size-8 rounded-full",
190
+ orientation === "horizontal"
191
+ ? "top-1/2 -left-12 -translate-y-1/2"
192
+ : "-top-12 left-1/2 -translate-x-1/2 rotate-90",
192
193
  className
193
194
  )}
194
195
  data-slot="carousel-previous"
@@ -206,8 +207,8 @@ function CarouselPrevious({
206
207
 
207
208
  function CarouselNext({
208
209
  className,
209
- variant = 'outline',
210
- size = 'icon',
210
+ variant = "outline",
211
+ size = "icon",
211
212
  ...props
212
213
  }: React.ComponentProps<typeof Button>) {
213
214
  const { orientation, scrollNext, canScrollNext } = useCarousel();
@@ -215,10 +216,10 @@ function CarouselNext({
215
216
  return (
216
217
  <Button
217
218
  className={cn(
218
- 'absolute size-8 rounded-full',
219
- orientation === 'horizontal'
220
- ? 'top-1/2 -right-12 -translate-y-1/2'
221
- : '-bottom-12 left-1/2 -translate-x-1/2 rotate-90',
219
+ "absolute size-8 rounded-full",
220
+ orientation === "horizontal"
221
+ ? "top-1/2 -right-12 -translate-y-1/2"
222
+ : "-bottom-12 left-1/2 -translate-x-1/2 rotate-90",
222
223
  className
223
224
  )}
224
225
  data-slot="carousel-next"
@@ -1,4 +1,4 @@
1
- import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
1
+ import * as CollapsiblePrimitive from "@radix-ui/react-collapsible";
2
2
 
3
3
  function Collapsible({
4
4
  ...props