larkup 0.1.14

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 (141) hide show
  1. package/.env +2 -0
  2. package/app/actions/vercel.ts +417 -0
  3. package/app/api/chat/route.ts +192 -0
  4. package/app/api/chat/status/route.ts +55 -0
  5. package/app/api/chat/suggestions/route.ts +115 -0
  6. package/app/api/config/route.ts +73 -0
  7. package/app/api/config/test/route.ts +67 -0
  8. package/app/api/config/test-embedding/route.ts +40 -0
  9. package/app/api/config/test-llm/route.ts +47 -0
  10. package/app/api/config/test-provider/route.ts +36 -0
  11. package/app/api/demo/route.ts +176 -0
  12. package/app/api/deploy/ssh/route.ts +340 -0
  13. package/app/api/documents/route.ts +90 -0
  14. package/app/api/firecrawl/local/route.ts +46 -0
  15. package/app/api/index/route.ts +113 -0
  16. package/app/api/jobs/[id]/route.ts +44 -0
  17. package/app/api/jobs/route.ts +116 -0
  18. package/app/api/parse-file/route.ts +39 -0
  19. package/app/api/search/google/route.ts +162 -0
  20. package/app/api/search/route.ts +29 -0
  21. package/app/api/server/download/route.ts +112 -0
  22. package/app/api/server/generate/route.ts +46 -0
  23. package/app/api/server/local/route.ts +42 -0
  24. package/app/api/servers/route.ts +137 -0
  25. package/app/api/vector-stores/install/route.ts +65 -0
  26. package/app/api/vector-stores/status/route.ts +26 -0
  27. package/app/chat/page.tsx +15 -0
  28. package/app/configure/page.tsx +53 -0
  29. package/app/data/page.tsx +15 -0
  30. package/app/demo/page.tsx +15 -0
  31. package/app/favicon.ico +0 -0
  32. package/app/globals.css +190 -0
  33. package/app/index-data/page.tsx +15 -0
  34. package/app/layout.tsx +51 -0
  35. package/app/page.tsx +34 -0
  36. package/app/server/page.tsx +22 -0
  37. package/app/simple/chat/page.tsx +17 -0
  38. package/app/simple/docs/page.tsx +21 -0
  39. package/app/simple/layout.tsx +9 -0
  40. package/app/simple/settings/page.tsx +627 -0
  41. package/app/template.tsx +16 -0
  42. package/app/themes.css +733 -0
  43. package/components/alerts/generic-alert.tsx +74 -0
  44. package/components/app-sidebar.tsx +187 -0
  45. package/components/app-topnav.tsx +195 -0
  46. package/components/chat/chat-settings-modal.tsx +209 -0
  47. package/components/chat/chat-workspace.tsx +348 -0
  48. package/components/chat/knowledge-base-result.tsx +97 -0
  49. package/components/chat/message-item.tsx +103 -0
  50. package/components/client-layout-wrapper.tsx +182 -0
  51. package/components/configure/configure-form.tsx +1683 -0
  52. package/components/configure/store-fields.tsx +152 -0
  53. package/components/data/corpus-panel.tsx +499 -0
  54. package/components/data/data-workspace.tsx +272 -0
  55. package/components/data/firecrawl-notice.tsx +236 -0
  56. package/components/data/jobs-panel.tsx +485 -0
  57. package/components/data/paste-panel.tsx +79 -0
  58. package/components/data/scrape-panel.tsx +964 -0
  59. package/components/data/upload-panel.tsx +714 -0
  60. package/components/demo/demo-workspace.tsx +419 -0
  61. package/components/global-settings.tsx +286 -0
  62. package/components/index/index-workspace.tsx +482 -0
  63. package/components/onboarding/simple-setup.tsx +702 -0
  64. package/components/onboarding/tech-setup.tsx +121 -0
  65. package/components/onboarding/welcome-screen.tsx +183 -0
  66. package/components/page-header.tsx +44 -0
  67. package/components/server/code-viewer.tsx +87 -0
  68. package/components/server/deploy-button.tsx +1390 -0
  69. package/components/server/server-workspace.tsx +392 -0
  70. package/components/simple/sdk-connect-dialog.tsx +201 -0
  71. package/components/simple/simple-index-button.tsx +83 -0
  72. package/components/simple/simple-sidebar.tsx +161 -0
  73. package/components/theme-customizer-provider.tsx +171 -0
  74. package/components/theme-switcher.tsx +445 -0
  75. package/components/ui/alert-dialog.tsx +187 -0
  76. package/components/ui/alert.tsx +76 -0
  77. package/components/ui/badge.tsx +52 -0
  78. package/components/ui/button.tsx +59 -0
  79. package/components/ui/card.tsx +103 -0
  80. package/components/ui/checkbox.tsx +28 -0
  81. package/components/ui/collapsible.tsx +21 -0
  82. package/components/ui/dialog.tsx +159 -0
  83. package/components/ui/dropdown-menu.tsx +281 -0
  84. package/components/ui/input.tsx +22 -0
  85. package/components/ui/label.tsx +20 -0
  86. package/components/ui/popover.tsx +90 -0
  87. package/components/ui/progress.tsx +83 -0
  88. package/components/ui/provider-icon.tsx +94 -0
  89. package/components/ui/scroll-area.tsx +55 -0
  90. package/components/ui/select.tsx +248 -0
  91. package/components/ui/separator.tsx +25 -0
  92. package/components/ui/sheet.tsx +138 -0
  93. package/components/ui/skeleton.tsx +13 -0
  94. package/components/ui/sonner.tsx +63 -0
  95. package/components/ui/switch.tsx +32 -0
  96. package/components/ui/table.tsx +116 -0
  97. package/components/ui/tabs.tsx +84 -0
  98. package/components/ui/textarea.tsx +18 -0
  99. package/components/ui/tooltip.tsx +66 -0
  100. package/components/workspace/delete-server-dialog.tsx +71 -0
  101. package/components/workspace/server-form-dialog.tsx +103 -0
  102. package/components/workspace/server-switcher.tsx +163 -0
  103. package/components/workspace/workspace-provider.tsx +177 -0
  104. package/components/workspace/workspace-top-bar.tsx +23 -0
  105. package/components.json +21 -0
  106. package/lib/error-formatter.ts +15 -0
  107. package/lib/utils.ts +6 -0
  108. package/next-env.d.ts +6 -0
  109. package/next.config.mjs +18 -0
  110. package/package.json +65 -0
  111. package/postcss.config.mjs +8 -0
  112. package/public/docker.png +0 -0
  113. package/public/favicon.ico +0 -0
  114. package/public/github.svg +3 -0
  115. package/public/hetzner.svg +1 -0
  116. package/public/icons/aws.svg +38 -0
  117. package/public/icons/azure.svg +1 -0
  118. package/public/icons/chroma.png +0 -0
  119. package/public/icons/cohere.svg +30 -0
  120. package/public/icons/digital-ocean.webp +0 -0
  121. package/public/icons/firecrawl2.png +0 -0
  122. package/public/icons/gcp.svg +1 -0
  123. package/public/icons/gemini.svg +1 -0
  124. package/public/icons/jina.svg +1 -0
  125. package/public/icons/lancedb2.png +0 -0
  126. package/public/icons/mistral.svg +469 -0
  127. package/public/icons/nomic.png +0 -0
  128. package/public/icons/openai.svg +1 -0
  129. package/public/icons/pgvector2.png +0 -0
  130. package/public/icons/pinecone.png +0 -0
  131. package/public/icons/qdrant.svg +35 -0
  132. package/public/icons/supabase.png +0 -0
  133. package/public/icons/vercel copy.svg +1 -0
  134. package/public/icons/vercel.svg +1 -0
  135. package/public/icons/voyage-light.png +0 -0
  136. package/public/icons/weaviate.webp +0 -0
  137. package/public/logo-light.png +0 -0
  138. package/public/logo.png +0 -0
  139. package/public/logo9.png +0 -0
  140. package/public/vercel.svg +1 -0
  141. package/tsconfig.json +33 -0
@@ -0,0 +1,161 @@
1
+ "use client"
2
+
3
+ import Link from "next/link"
4
+ import { usePathname } from "next/navigation"
5
+ import {
6
+ MessageCircle,
7
+ FileStack,
8
+ SlidersHorizontal,
9
+ type LucideIcon,
10
+ } from "lucide-react"
11
+ import { cn } from "@/lib/utils"
12
+ import {
13
+ Tooltip,
14
+ TooltipContent,
15
+ TooltipProvider,
16
+ TooltipTrigger,
17
+ } from "@/components/ui/tooltip"
18
+ import { useThemeCustomizer, type PanelBgVariant } from "@/components/theme-customizer-provider"
19
+ import { ThemeSwitcher } from "@/components/theme-switcher"
20
+
21
+ const NAV_BG_COLORS: Record<PanelBgVariant, string | undefined> = {
22
+ "panel-default": undefined,
23
+ "panel-white": "#FFFFFF",
24
+ "panel-fafafa": "#F4F4F4",
25
+ "panel-warm": "#F7F1EA",
26
+ "panel-soft": "#FBFAF8",
27
+ "panel-silver": "#F8F8F8",
28
+ "panel-stone": "#F5F5F2",
29
+ }
30
+
31
+ interface NavItem {
32
+ id: string
33
+ label: string
34
+ href: string
35
+ icon: LucideIcon
36
+ description: string
37
+ }
38
+
39
+ const SIMPLE_NAV: NavItem[] = [
40
+ {
41
+ id: "chat",
42
+ label: "Chat",
43
+ href: "/simple/chat",
44
+ icon: MessageCircle,
45
+ description: "Chat with your knowledge base using AI.",
46
+ },
47
+ {
48
+ id: "docs",
49
+ label: "Docs",
50
+ href: "/simple/docs",
51
+ icon: FileStack,
52
+ description: "Upload, paste, or manage your documents.",
53
+ },
54
+ {
55
+ id: "settings",
56
+ label: "Settings",
57
+ href: "/simple/settings",
58
+ icon: SlidersHorizontal,
59
+ description: "Configure provider, API keys, and advanced settings.",
60
+ },
61
+ ]
62
+
63
+ export function SimpleSidebar() {
64
+ const pathname = usePathname()
65
+ const { pageStyle, navBg } = useThemeCustomizer()
66
+
67
+ const navColor = navBg ? NAV_BG_COLORS[navBg] : undefined
68
+ const navStyle = navColor ? { backgroundColor: navColor } : undefined
69
+
70
+ return (
71
+ <TooltipProvider delay={150}>
72
+ <aside
73
+ className={cn(
74
+ "sticky top-0 hidden h-screen w-[84px] shrink-0 flex-col items-center gap-1 self-start py-3 md:flex",
75
+ !navColor ? "bg-background" : "",
76
+ pageStyle === "fused" ? "border-r border-border" : "",
77
+ )}
78
+ style={navStyle}
79
+ >
80
+ {/* Brand */}
81
+ <Tooltip>
82
+ <TooltipTrigger
83
+ render={
84
+ <Link
85
+ href="/simple/chat"
86
+ aria-label="larkup home"
87
+ className="mb-2 flex size-11 items-center justify-center rounded-xl bg-primary text-primary-foreground shadow-sm transition-transform hover:scale-105"
88
+ />
89
+ }
90
+ >
91
+ <img src={"/logo9.png"} className="size-6.5" alt="logo" />
92
+ </TooltipTrigger>
93
+ <TooltipContent side="right" sideOffset={10}>
94
+ Larkup
95
+ </TooltipContent>
96
+ </Tooltip>
97
+
98
+ {/* Navigation */}
99
+ <nav className="flex flex-1 flex-col items-center gap-1.5">
100
+ {SIMPLE_NAV.map((item) => {
101
+ const Icon = item.icon
102
+ const active = pathname?.startsWith(item.href)
103
+
104
+ return (
105
+ <Tooltip key={item.id}>
106
+ <TooltipTrigger
107
+ render={
108
+ <Link
109
+ href={item.href}
110
+ aria-current={active ? "page" : undefined}
111
+ className="group relative flex w-16 flex-col items-center gap-1.5 rounded-2xl py-2 outline-none focus-visible:ring-2 focus-visible:ring-ring"
112
+ />
113
+ }
114
+ >
115
+ {/* Active accent bar */}
116
+ <span
117
+ className={cn(
118
+ "absolute left-0 top-1/2 h-7 w-1 -translate-y-1/2 rounded-r-full bg-primary transition-opacity",
119
+ active ? "opacity-100" : "opacity-0",
120
+ )}
121
+ />
122
+ <span
123
+ className={cn(
124
+ "relative flex size-10 items-center justify-center rounded-xl transition-colors",
125
+ active
126
+ ? "bg-white border text-primary"
127
+ : "text-foreground/70 group-hover:bg-white/90 group-hover:text-foreground",
128
+ )}
129
+ >
130
+ <Icon className="size-[19px]" strokeWidth={active ? 2.25 : 2} />
131
+ </span>
132
+ <span
133
+ className={cn(
134
+ "text-[10.5px] leading-none tracking-tight",
135
+ active
136
+ ? "font-semibold text-primary"
137
+ : "text-muted-foreground",
138
+ )}
139
+ >
140
+ {item.label}
141
+ </span>
142
+ </TooltipTrigger>
143
+ <TooltipContent side="right" sideOffset={10} className="max-w-56">
144
+ <div className="flex flex-col gap-0.5">
145
+ <span className="font-medium">{item.label}</span>
146
+ <span className="text-[11px] leading-snug opacity-80">
147
+ {item.description}
148
+ </span>
149
+ </div>
150
+ </TooltipContent>
151
+ </Tooltip>
152
+ )
153
+ })}
154
+ </nav>
155
+
156
+ {/* Footer */}
157
+ <ThemeSwitcher floating={false} />
158
+ </aside>
159
+ </TooltipProvider>
160
+ )
161
+ }
@@ -0,0 +1,171 @@
1
+ "use client";
2
+
3
+ import React, { createContext, useContext, useEffect, useState } from "react";
4
+
5
+ export type ThemeVariant =
6
+ | "default"
7
+ | "theme-gaia"
8
+ | "theme-docker"
9
+ | "theme-pinecone"
10
+ | "theme-vercel"
11
+ | "theme-elevenlabs"
12
+ | "theme-espresso"
13
+ | "theme-sienna"
14
+ | "theme-caramel";
15
+
16
+ export type BackgroundVariant =
17
+ | "bg-default"
18
+ | "bg-warm"
19
+ | "bg-soft"
20
+ | "bg-pure"
21
+ | "bg-silver"
22
+ | "bg-sage"
23
+ | "bg-stone";
24
+
25
+ export type PanelBgVariant =
26
+ | "panel-default"
27
+ | "panel-white"
28
+ | "panel-fafafa"
29
+ | "panel-warm"
30
+ | "panel-soft"
31
+ | "panel-silver"
32
+ | "panel-stone";
33
+
34
+ export type LayoutVariant = "sidebar" | "topnav" | "collapsed";
35
+
36
+ export type RadiusVariant =
37
+ | "radius-0"
38
+ | "radius-sm"
39
+ | "radius-default"
40
+ | "radius-lg";
41
+
42
+ export type PageStyleVariant = "card" | "fused";
43
+
44
+ interface ThemeCustomizerContextValue {
45
+ theme: ThemeVariant;
46
+ setTheme: (theme: ThemeVariant) => void;
47
+ layout: LayoutVariant;
48
+ setLayout: (layout: LayoutVariant) => void;
49
+ radius: RadiusVariant;
50
+ setRadius: (radius: RadiusVariant) => void;
51
+ background: BackgroundVariant;
52
+ setBackground: (bg: BackgroundVariant) => void;
53
+ panelBg: PanelBgVariant;
54
+ setPanelBg: (bg: PanelBgVariant) => void;
55
+ navBg: PanelBgVariant;
56
+ setNavBg: (bg: PanelBgVariant) => void;
57
+ pageStyle: PageStyleVariant;
58
+ setPageStyle: (style: PageStyleVariant) => void;
59
+ isMounted: boolean;
60
+ }
61
+
62
+ const ThemeCustomizerContext =
63
+ createContext<ThemeCustomizerContextValue | null>(null);
64
+
65
+ export function useThemeCustomizer() {
66
+ const ctx = useContext(ThemeCustomizerContext);
67
+ if (!ctx) {
68
+ throw new Error(
69
+ "useThemeCustomizer must be used within a ThemeCustomizerProvider",
70
+ );
71
+ }
72
+ return ctx;
73
+ }
74
+
75
+ export function ThemeCustomizerProvider({
76
+ children,
77
+ }: {
78
+ children: React.ReactNode;
79
+ }) {
80
+ const [isMounted, setIsMounted] = useState(false);
81
+ // Default to "default" theme (black primary). User can switch themes freely.
82
+ const [theme, setThemeState] = useState<ThemeVariant>("default");
83
+ const [layout, setLayout] = useState<LayoutVariant>("sidebar");
84
+ const [radius, setRadius] = useState<RadiusVariant>("radius-default");
85
+ const [background, setBackground] = useState<BackgroundVariant>("bg-default");
86
+ const [panelBg, setPanelBg] = useState<PanelBgVariant>("panel-white");
87
+ const [navBg, setNavBg] = useState<PanelBgVariant>("panel-silver");
88
+ const [pageStyle, setPageStyle] = useState<PageStyleVariant>("card");
89
+
90
+ useEffect(() => {
91
+ setIsMounted(true);
92
+
93
+ const savedTheme = localStorage.getItem("app-theme") as ThemeVariant;
94
+ const savedLayout = localStorage.getItem("app-layout") as LayoutVariant;
95
+ const savedRadius = localStorage.getItem("app-radius") as RadiusVariant;
96
+ const savedBackground = localStorage.getItem(
97
+ "app-background",
98
+ ) as BackgroundVariant;
99
+ const savedPanelBg = localStorage.getItem(
100
+ "app-panel-bg",
101
+ ) as PanelBgVariant;
102
+ const savedNavBg = localStorage.getItem(
103
+ "app-nav-bg",
104
+ ) as PanelBgVariant;
105
+ const savedPageStyle = localStorage.getItem(
106
+ "app-pagestyle",
107
+ ) as PageStyleVariant;
108
+
109
+ if (savedTheme) setThemeState(savedTheme);
110
+ if (savedLayout) setLayout(savedLayout);
111
+ if (savedRadius) setRadius(savedRadius);
112
+ if (savedBackground) setBackground(savedBackground);
113
+ if (savedPanelBg) setPanelBg(savedPanelBg);
114
+ if (savedNavBg) setNavBg(savedNavBg);
115
+ if (savedPageStyle) setPageStyle(savedPageStyle);
116
+ }, []);
117
+
118
+ useEffect(() => {
119
+ if (!isMounted) return;
120
+ localStorage.setItem("app-theme", theme);
121
+ localStorage.setItem("app-layout", layout);
122
+ localStorage.setItem("app-radius", radius);
123
+ localStorage.setItem("app-background", background);
124
+ localStorage.setItem("app-panel-bg", panelBg);
125
+ localStorage.setItem("app-nav-bg", navBg);
126
+ localStorage.setItem("app-pagestyle", pageStyle);
127
+
128
+ // Update body classes
129
+ const body = document.body;
130
+
131
+ // Remove old classes
132
+ Array.from(body.classList).forEach((cls) => {
133
+ if (
134
+ cls.startsWith("theme-") ||
135
+ cls.startsWith("radius-") ||
136
+ cls.startsWith("bg-")
137
+ ) {
138
+ body.classList.remove(cls);
139
+ }
140
+ });
141
+
142
+ // Add new classes
143
+ if (theme !== "default") body.classList.add(theme);
144
+ if (radius !== "radius-default") body.classList.add(radius);
145
+ if (background) body.classList.add(background);
146
+ }, [theme, layout, radius, background, panelBg, navBg, pageStyle, isMounted]);
147
+
148
+ return (
149
+ <ThemeCustomizerContext.Provider
150
+ value={{
151
+ theme,
152
+ setTheme: setThemeState,
153
+ layout,
154
+ setLayout,
155
+ radius,
156
+ setRadius,
157
+ background,
158
+ setBackground,
159
+ panelBg,
160
+ setPanelBg,
161
+ navBg,
162
+ setNavBg,
163
+ pageStyle,
164
+ setPageStyle,
165
+ isMounted,
166
+ }}
167
+ >
168
+ {children}
169
+ </ThemeCustomizerContext.Provider>
170
+ );
171
+ }