Gardening (#540)
This commit is contained in:
commit
f23c73f6a5
65 changed files with 457 additions and 325 deletions
|
|
@ -6,29 +6,10 @@
|
||||||
"prettier",
|
"prettier",
|
||||||
"plugin:tailwindcss/recommended"
|
"plugin:tailwindcss/recommended"
|
||||||
],
|
],
|
||||||
"plugins": ["import", "tailwindcss"],
|
"plugins": ["tailwindcss"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"tailwindcss/no-custom-classname": "off",
|
"tailwindcss/no-custom-classname": "off",
|
||||||
"tailwindcss/classnames-order": "off",
|
"tailwindcss/classnames-order": "off"
|
||||||
"import/order": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"groups": [
|
|
||||||
"builtin",
|
|
||||||
"external",
|
|
||||||
"internal",
|
|
||||||
["parent", "sibling"],
|
|
||||||
"index",
|
|
||||||
"object",
|
|
||||||
"type"
|
|
||||||
],
|
|
||||||
"newlines-between": "always",
|
|
||||||
"alphabetize": {
|
|
||||||
"order": "asc",
|
|
||||||
"caseInsensitive": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"import/resolver": {
|
"import/resolver": {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { createUser, getUser } from '@/db/queries';
|
import { createUser, getUser } from '@/lib/db/queries';
|
||||||
|
|
||||||
import { signIn } from './auth';
|
import { signIn } from './auth';
|
||||||
|
|
||||||
|
|
@ -61,7 +61,7 @@ export const register = async (
|
||||||
password: formData.get('password'),
|
password: formData.get('password'),
|
||||||
});
|
});
|
||||||
|
|
||||||
let [user] = await getUser(validatedData.email);
|
const [user] = await getUser(validatedData.email);
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
return { status: 'user_exists' } as RegisterActionState;
|
return { status: 'user_exists' } as RegisterActionState;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { NextAuthConfig } from 'next-auth';
|
import type { NextAuthConfig } from 'next-auth';
|
||||||
|
|
||||||
export const authConfig = {
|
export const authConfig = {
|
||||||
pages: {
|
pages: {
|
||||||
|
|
@ -11,10 +11,10 @@ export const authConfig = {
|
||||||
],
|
],
|
||||||
callbacks: {
|
callbacks: {
|
||||||
authorized({ auth, request: { nextUrl } }) {
|
authorized({ auth, request: { nextUrl } }) {
|
||||||
let isLoggedIn = !!auth?.user;
|
const isLoggedIn = !!auth?.user;
|
||||||
let isOnChat = nextUrl.pathname.startsWith('/');
|
const isOnChat = nextUrl.pathname.startsWith('/');
|
||||||
let isOnRegister = nextUrl.pathname.startsWith('/register');
|
const isOnRegister = nextUrl.pathname.startsWith('/register');
|
||||||
let isOnLogin = nextUrl.pathname.startsWith('/login');
|
const isOnLogin = nextUrl.pathname.startsWith('/login');
|
||||||
|
|
||||||
if (isLoggedIn && (isOnLogin || isOnRegister)) {
|
if (isLoggedIn && (isOnLogin || isOnRegister)) {
|
||||||
return Response.redirect(new URL('/', nextUrl as unknown as URL));
|
return Response.redirect(new URL('/', nextUrl as unknown as URL));
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ import { compare } from 'bcrypt-ts';
|
||||||
import NextAuth, { User, Session } from 'next-auth';
|
import NextAuth, { User, Session } from 'next-auth';
|
||||||
import Credentials from 'next-auth/providers/credentials';
|
import Credentials from 'next-auth/providers/credentials';
|
||||||
|
|
||||||
import { getUser } from '@/db/queries';
|
import { getUser } from '@/lib/db/queries';
|
||||||
|
|
||||||
import { authConfig } from './auth.config';
|
import { authConfig } from './auth.config';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import { useRouter } from 'next/navigation';
|
||||||
import { useActionState, useEffect, useState } from 'react';
|
import { useActionState, useEffect, useState } from 'react';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
|
|
||||||
import { AuthForm } from '@/components/custom/auth-form';
|
import { AuthForm } from '@/components/auth-form';
|
||||||
import { SubmitButton } from '@/components/custom/submit-button';
|
import { SubmitButton } from '@/components/submit-button';
|
||||||
|
|
||||||
import { login, LoginActionState } from '../actions';
|
import { login, LoginActionState } from '../actions';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ import { useRouter } from 'next/navigation';
|
||||||
import { useActionState, useEffect, useState } from 'react';
|
import { useActionState, useEffect, useState } from 'react';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
|
|
||||||
import { AuthForm } from '@/components/custom/auth-form';
|
import { AuthForm } from '@/components/auth-form';
|
||||||
import { SubmitButton } from '@/components/custom/submit-button';
|
import { SubmitButton } from '@/components/submit-button';
|
||||||
|
|
||||||
import { register, RegisterActionState } from '../actions';
|
import { register, type RegisterActionState } from '../actions';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export async function generateTitleFromUserMessage({
|
||||||
message: CoreUserMessage;
|
message: CoreUserMessage;
|
||||||
}) {
|
}) {
|
||||||
const { text: title } = await generateText({
|
const { text: title } = await generateText({
|
||||||
model: customModel('gpt-3.5-turbo'),
|
model: customModel('gpt-4o-mini'),
|
||||||
system: `\n
|
system: `\n
|
||||||
- you will generate a short title based on the first message a user begins a conversation with
|
- you will generate a short title based on the first message a user begins a conversation with
|
||||||
- ensure it is not more than 80 characters long
|
- ensure it is not more than 80 characters long
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ import {
|
||||||
saveDocument,
|
saveDocument,
|
||||||
saveMessages,
|
saveMessages,
|
||||||
saveSuggestions,
|
saveSuggestions,
|
||||||
} from '@/db/queries';
|
} from '@/lib/db/queries';
|
||||||
import { Suggestion } from '@/db/schema';
|
import { Suggestion } from '@/lib/db/schema';
|
||||||
import {
|
import {
|
||||||
generateUUID,
|
generateUUID,
|
||||||
getMostRecentUserMessage,
|
getMostRecentUserMessage,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import {
|
||||||
deleteDocumentsByIdAfterTimestamp,
|
deleteDocumentsByIdAfterTimestamp,
|
||||||
getDocumentsById,
|
getDocumentsById,
|
||||||
saveDocument,
|
saveDocument,
|
||||||
} from '@/db/queries';
|
} from '@/lib/db/queries';
|
||||||
|
|
||||||
export async function GET(request: Request) {
|
export async function GET(request: Request) {
|
||||||
const { searchParams } = new URL(request.url);
|
const { searchParams } = new URL(request.url);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { auth } from '@/app/(auth)/auth';
|
import { auth } from '@/app/(auth)/auth';
|
||||||
import { getChatsByUserId } from '@/db/queries';
|
import { getChatsByUserId } from '@/lib/db/queries';
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const session = await auth();
|
const session = await auth();
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { auth } from '@/app/(auth)/auth';
|
import { auth } from '@/app/(auth)/auth';
|
||||||
import { getSuggestionsByDocumentId } from '@/db/queries';
|
import { getSuggestionsByDocumentId } from '@/lib/db/queries';
|
||||||
|
|
||||||
export async function GET(request: Request) {
|
export async function GET(request: Request) {
|
||||||
const { searchParams } = new URL(request.url);
|
const { searchParams } = new URL(request.url);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { auth } from '@/app/(auth)/auth';
|
import { auth } from '@/app/(auth)/auth';
|
||||||
import { getVotesByChatId, voteMessage } from '@/db/queries';
|
import { getVotesByChatId, voteMessage } from '@/lib/db/queries';
|
||||||
|
|
||||||
export async function GET(request: Request) {
|
export async function GET(request: Request) {
|
||||||
const { searchParams } = new URL(request.url);
|
const { searchParams } = new URL(request.url);
|
||||||
|
|
|
||||||
|
|
@ -4,8 +4,8 @@ import { notFound } from 'next/navigation';
|
||||||
|
|
||||||
import { DEFAULT_MODEL_NAME, models } from '@/ai/models';
|
import { DEFAULT_MODEL_NAME, models } from '@/ai/models';
|
||||||
import { auth } from '@/app/(auth)/auth';
|
import { auth } from '@/app/(auth)/auth';
|
||||||
import { Chat as PreviewChat } from '@/components/custom/chat';
|
import { Chat as PreviewChat } from '@/components/chat';
|
||||||
import { getChatById, getMessagesByChatId } from '@/db/queries';
|
import { getChatById, getMessagesByChatId } from '@/lib/db/queries';
|
||||||
import { convertToUIMessages } from '@/lib/utils';
|
import { convertToUIMessages } from '@/lib/utils';
|
||||||
|
|
||||||
export default async function Page(props: { params: Promise<any> }) {
|
export default async function Page(props: { params: Promise<any> }) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { cookies } from 'next/headers';
|
import { cookies } from 'next/headers';
|
||||||
|
|
||||||
import { AppSidebar } from '@/components/custom/app-sidebar';
|
import { AppSidebar } from '@/components/app-sidebar';
|
||||||
import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar';
|
import { SidebarInset, SidebarProvider } from '@/components/ui/sidebar';
|
||||||
|
|
||||||
import { auth } from '../(auth)/auth';
|
import { auth } from '../(auth)/auth';
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { cookies } from 'next/headers';
|
import { cookies } from 'next/headers';
|
||||||
|
|
||||||
import { DEFAULT_MODEL_NAME, models } from '@/ai/models';
|
import { DEFAULT_MODEL_NAME, models } from '@/ai/models';
|
||||||
import { Chat } from '@/components/custom/chat';
|
import { Chat } from '@/components/chat';
|
||||||
import { generateUUID } from '@/lib/utils';
|
import { generateUUID } from '@/lib/utils';
|
||||||
|
|
||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
|
|
|
||||||
|
|
@ -104,17 +104,17 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'geist';
|
font-family: "geist";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 100 900;
|
font-weight: 100 900;
|
||||||
src: url(/fonts/geist.woff2) format('woff2');
|
src: url(/fonts/geist.woff2) format("woff2");
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'geist-mono';
|
font-family: "geist-mono";
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 100 900;
|
font-weight: 100 900;
|
||||||
src: url(/fonts/geist-mono.woff2) format('woff2');
|
src: url(/fonts/geist-mono.woff2) format("woff2");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,7 +123,7 @@
|
||||||
pointer-events: none !important;
|
pointer-events: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
*[class^='text-'] {
|
*[class^="text-"] {
|
||||||
color: transparent;
|
color: transparent;
|
||||||
@apply rounded-md bg-foreground/20 select-none animate-pulse;
|
@apply rounded-md bg-foreground/20 select-none animate-pulse;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { Metadata } from 'next';
|
import { Metadata } from 'next';
|
||||||
import { Toaster } from 'sonner';
|
import { Toaster } from 'sonner';
|
||||||
|
|
||||||
import { ThemeProvider } from '@/components/custom/theme-provider';
|
import { ThemeProvider } from '@/components/theme-provider';
|
||||||
|
|
||||||
import './globals.css';
|
import './globals.css';
|
||||||
|
|
||||||
|
|
|
||||||
58
biome.json
Normal file
58
biome.json
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
{
|
||||||
|
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
||||||
|
"vcs": { "enabled": false, "clientKind": "git", "useIgnoreFile": true },
|
||||||
|
"files": {
|
||||||
|
"ignoreUnknown": false,
|
||||||
|
"ignore": [
|
||||||
|
"**/pnpm-lock.yaml",
|
||||||
|
"lib/db/migrations",
|
||||||
|
"lib/editor/react-renderer.tsx",
|
||||||
|
"node_modules",
|
||||||
|
".next",
|
||||||
|
"public",
|
||||||
|
".vercel"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"formatter": {
|
||||||
|
"enabled": true,
|
||||||
|
"useEditorconfig": true,
|
||||||
|
"formatWithErrors": false,
|
||||||
|
"indentStyle": "space",
|
||||||
|
"indentWidth": 2,
|
||||||
|
"lineEnding": "lf",
|
||||||
|
"lineWidth": 80,
|
||||||
|
"attributePosition": "auto",
|
||||||
|
"bracketSpacing": true,
|
||||||
|
"ignore": ["**/pnpm-lock.yaml", "lib/db/drizzle"]
|
||||||
|
},
|
||||||
|
"organizeImports": { "enabled": true },
|
||||||
|
"linter": {
|
||||||
|
"enabled": true,
|
||||||
|
"rules": {
|
||||||
|
"recommended": true,
|
||||||
|
"a11y": {
|
||||||
|
"noSvgWithoutTitle": "off",
|
||||||
|
"useKeyWithClickEvents": "off"
|
||||||
|
},
|
||||||
|
"style": {
|
||||||
|
"noNonNullAssertion": "off"
|
||||||
|
},
|
||||||
|
"correctness": {
|
||||||
|
"useExhaustiveDependencies": "off"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"javascript": {
|
||||||
|
"formatter": {
|
||||||
|
"jsxQuoteStyle": "double",
|
||||||
|
"quoteProperties": "asNeeded",
|
||||||
|
"trailingCommas": "es5",
|
||||||
|
"semicolons": "always",
|
||||||
|
"arrowParentheses": "always",
|
||||||
|
"bracketSameLine": false,
|
||||||
|
"quoteStyle": "single",
|
||||||
|
"attributePosition": "auto",
|
||||||
|
"bracketSpacing": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,9 +4,9 @@ import Link from 'next/link';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { type User } from 'next-auth';
|
import { type User } from 'next-auth';
|
||||||
|
|
||||||
import { PlusIcon } from '@/components/custom/icons';
|
import { PlusIcon } from '@/components/icons';
|
||||||
import { SidebarHistory } from '@/components/custom/sidebar-history';
|
import { SidebarHistory } from '@/components/sidebar-history';
|
||||||
import { SidebarUserNav } from '@/components/custom/sidebar-user-nav';
|
import { SidebarUserNav } from '@/components/sidebar-user-nav';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import {
|
import {
|
||||||
Sidebar,
|
Sidebar,
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import Form from 'next/form';
|
import Form from 'next/form';
|
||||||
|
|
||||||
import { Input } from '../ui/input';
|
import { Input } from './ui/input';
|
||||||
import { Label } from '../ui/label';
|
import { Label } from './ui/label';
|
||||||
|
|
||||||
export function AuthForm({
|
export function AuthForm({
|
||||||
action,
|
action,
|
||||||
|
|
@ -17,7 +17,7 @@ import {
|
||||||
useWindowSize,
|
useWindowSize,
|
||||||
} from 'usehooks-ts';
|
} from 'usehooks-ts';
|
||||||
|
|
||||||
import { Document, Suggestion, Vote } from '@/db/schema';
|
import { Document, Suggestion, Vote } from '@/lib/db/schema';
|
||||||
import { fetcher } from '@/lib/utils';
|
import { fetcher } from '@/lib/utils';
|
||||||
|
|
||||||
import { DiffView } from './diffview';
|
import { DiffView } from './diffview';
|
||||||
|
|
@ -27,10 +27,10 @@ import { CopyIcon, CrossIcon, DeltaIcon, RedoIcon, UndoIcon } from './icons';
|
||||||
import { PreviewMessage } from './message';
|
import { PreviewMessage } from './message';
|
||||||
import { MultimodalInput } from './multimodal-input';
|
import { MultimodalInput } from './multimodal-input';
|
||||||
import { Toolbar } from './toolbar';
|
import { Toolbar } from './toolbar';
|
||||||
|
import { Button } from './ui/button';
|
||||||
|
import { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip';
|
||||||
import { useScrollToBottom } from './use-scroll-to-bottom';
|
import { useScrollToBottom } from './use-scroll-to-bottom';
|
||||||
import { VersionFooter } from './version-footer';
|
import { VersionFooter } from './version-footer';
|
||||||
import { Button } from '../ui/button';
|
|
||||||
import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';
|
|
||||||
export interface UIBlock {
|
export interface UIBlock {
|
||||||
title: string;
|
title: string;
|
||||||
documentId: string;
|
documentId: string;
|
||||||
|
|
@ -4,13 +4,13 @@ import Link from 'next/link';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { useWindowSize } from 'usehooks-ts';
|
import { useWindowSize } from 'usehooks-ts';
|
||||||
|
|
||||||
import { ModelSelector } from '@/components/custom/model-selector';
|
import { ModelSelector } from '@/components/model-selector';
|
||||||
import { SidebarToggle } from '@/components/custom/sidebar-toggle';
|
import { SidebarToggle } from '@/components/sidebar-toggle';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { BetterTooltip } from '@/components/ui/tooltip';
|
import { BetterTooltip } from '@/components/ui/tooltip';
|
||||||
|
|
||||||
import { PlusIcon, VercelIcon } from './icons';
|
import { PlusIcon, VercelIcon } from './icons';
|
||||||
import { useSidebar } from '../ui/sidebar';
|
import { useSidebar } from './ui/sidebar';
|
||||||
|
|
||||||
export function ChatHeader({ selectedModelId }: { selectedModelId: string }) {
|
export function ChatHeader({ selectedModelId }: { selectedModelId: string }) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
@ -7,10 +7,10 @@ import { useState } from 'react';
|
||||||
import useSWR, { useSWRConfig } from 'swr';
|
import useSWR, { useSWRConfig } from 'swr';
|
||||||
import { useWindowSize } from 'usehooks-ts';
|
import { useWindowSize } from 'usehooks-ts';
|
||||||
|
|
||||||
import { ChatHeader } from '@/components/custom/chat-header';
|
import { ChatHeader } from '@/components/chat-header';
|
||||||
import { PreviewMessage, ThinkingMessage } from '@/components/custom/message';
|
import { PreviewMessage, ThinkingMessage } from '@/components/message';
|
||||||
import { useScrollToBottom } from '@/components/custom/use-scroll-to-bottom';
|
import { useScrollToBottom } from '@/components/use-scroll-to-bottom';
|
||||||
import { Vote } from '@/db/schema';
|
import { Vote } from '@/lib/db/schema';
|
||||||
import { fetcher } from '@/lib/utils';
|
import { fetcher } from '@/lib/utils';
|
||||||
|
|
||||||
import { Block, UIBlock } from './block';
|
import { Block, UIBlock } from './block';
|
||||||
|
|
@ -6,7 +6,7 @@ import { EditorState } from 'prosemirror-state';
|
||||||
import { EditorView } from 'prosemirror-view';
|
import { EditorView } from 'prosemirror-view';
|
||||||
import React, { memo, useEffect, useRef } from 'react';
|
import React, { memo, useEffect, useRef } from 'react';
|
||||||
|
|
||||||
import { Suggestion } from '@/db/schema';
|
import { Suggestion } from '@/lib/db/schema';
|
||||||
import {
|
import {
|
||||||
documentSchema,
|
documentSchema,
|
||||||
handleTransaction,
|
handleTransaction,
|
||||||
|
|
@ -3,17 +3,17 @@ import { toast } from 'sonner';
|
||||||
import { useSWRConfig } from 'swr';
|
import { useSWRConfig } from 'swr';
|
||||||
import { useCopyToClipboard } from 'usehooks-ts';
|
import { useCopyToClipboard } from 'usehooks-ts';
|
||||||
|
|
||||||
import { Vote } from '@/db/schema';
|
import { Vote } from '@/lib/db/schema';
|
||||||
import { getMessageIdFromAnnotations } from '@/lib/utils';
|
import { getMessageIdFromAnnotations } from '@/lib/utils';
|
||||||
|
|
||||||
import { CopyIcon, ThumbDownIcon, ThumbUpIcon } from './icons';
|
import { CopyIcon, ThumbDownIcon, ThumbUpIcon } from './icons';
|
||||||
import { Button } from '../ui/button';
|
import { Button } from './ui/button';
|
||||||
import {
|
import {
|
||||||
Tooltip,
|
Tooltip,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipProvider,
|
TooltipProvider,
|
||||||
TooltipTrigger,
|
TooltipTrigger,
|
||||||
} from '../ui/tooltip';
|
} from './ui/tooltip';
|
||||||
|
|
||||||
export function MessageActions({
|
export function MessageActions({
|
||||||
chatId,
|
chatId,
|
||||||
|
|
@ -5,7 +5,7 @@ import cx from 'classnames';
|
||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import { Dispatch, SetStateAction } from 'react';
|
import { Dispatch, SetStateAction } from 'react';
|
||||||
|
|
||||||
import { Vote } from '@/db/schema';
|
import { Vote } from '@/lib/db/schema';
|
||||||
|
|
||||||
import { UIBlock } from './block';
|
import { UIBlock } from './block';
|
||||||
import { DocumentToolCall, DocumentToolResult } from './document';
|
import { DocumentToolCall, DocumentToolResult } from './document';
|
||||||
|
|
@ -19,8 +19,8 @@ import { sanitizeUIMessages } from '@/lib/utils';
|
||||||
|
|
||||||
import { ArrowUpIcon, PaperclipIcon, StopIcon } from './icons';
|
import { ArrowUpIcon, PaperclipIcon, StopIcon } from './icons';
|
||||||
import { PreviewAttachment } from './preview-attachment';
|
import { PreviewAttachment } from './preview-attachment';
|
||||||
import { Button } from '../ui/button';
|
import { Button } from './ui/button';
|
||||||
import { Textarea } from '../ui/textarea';
|
import { Textarea } from './ui/textarea';
|
||||||
|
|
||||||
const suggestedActions = [
|
const suggestedActions = [
|
||||||
{
|
{
|
||||||
|
|
@ -8,7 +8,7 @@ import { useEffect, useState } from 'react';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
import useSWR from 'swr';
|
import useSWR from 'swr';
|
||||||
|
|
||||||
import { MoreHorizontalIcon, TrashIcon } from '@/components/custom/icons';
|
import { MoreHorizontalIcon, TrashIcon } from '@/components/icons';
|
||||||
import {
|
import {
|
||||||
AlertDialog,
|
AlertDialog,
|
||||||
AlertDialogAction,
|
AlertDialogAction,
|
||||||
|
|
@ -34,7 +34,7 @@ import {
|
||||||
SidebarMenuItem,
|
SidebarMenuItem,
|
||||||
useSidebar,
|
useSidebar,
|
||||||
} from '@/components/ui/sidebar';
|
} from '@/components/ui/sidebar';
|
||||||
import { Chat } from '@/db/schema';
|
import { Chat } from '@/lib/db/schema';
|
||||||
import { fetcher } from '@/lib/utils';
|
import { fetcher } from '@/lib/utils';
|
||||||
|
|
||||||
type GroupedChats = {
|
type GroupedChats = {
|
||||||
|
|
@ -5,7 +5,7 @@ import { BetterTooltip } from '@/components/ui/tooltip';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
import { SidebarLeftIcon } from './icons';
|
import { SidebarLeftIcon } from './icons';
|
||||||
import { Button } from '../ui/button';
|
import { Button } from './ui/button';
|
||||||
|
|
||||||
export function SidebarToggle({
|
export function SidebarToggle({
|
||||||
className,
|
className,
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
import { useFormStatus } from 'react-dom';
|
import { useFormStatus } from 'react-dom';
|
||||||
|
|
||||||
import { LoaderIcon } from '@/components/custom/icons';
|
import { LoaderIcon } from '@/components/icons';
|
||||||
|
|
||||||
import { Button } from '../ui/button';
|
import { Button } from './ui/button';
|
||||||
|
|
||||||
export function SubmitButton({
|
export function SubmitButton({
|
||||||
children,
|
children,
|
||||||
|
|
@ -7,7 +7,7 @@ import { useWindowSize } from 'usehooks-ts';
|
||||||
import { UISuggestion } from '@/lib/editor/suggestions';
|
import { UISuggestion } from '@/lib/editor/suggestions';
|
||||||
|
|
||||||
import { CrossIcon, MessageIcon } from './icons';
|
import { CrossIcon, MessageIcon } from './icons';
|
||||||
import { Button } from '../ui/button';
|
import { Button } from './ui/button';
|
||||||
|
|
||||||
export const Suggestion = ({
|
export const Suggestion = ({
|
||||||
suggestion,
|
suggestion,
|
||||||
|
|
@ -26,7 +26,7 @@ import {
|
||||||
StopIcon,
|
StopIcon,
|
||||||
SummarizeIcon,
|
SummarizeIcon,
|
||||||
} from './icons';
|
} from './icons';
|
||||||
import { Button } from '../ui/button';
|
import { Button } from './ui/button';
|
||||||
|
|
||||||
type ToolProps = {
|
type ToolProps = {
|
||||||
type: 'final-polish' | 'request-suggestions' | 'adjust-reading-level';
|
type: 'final-polish' | 'request-suggestions' | 'adjust-reading-level';
|
||||||
|
|
@ -2,7 +2,7 @@ import { JSONValue } from 'ai';
|
||||||
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
|
import { Dispatch, SetStateAction, useEffect, useState } from 'react';
|
||||||
import { useSWRConfig } from 'swr';
|
import { useSWRConfig } from 'swr';
|
||||||
|
|
||||||
import { Suggestion } from '@/db/schema';
|
import { Suggestion } from '@/lib/db/schema';
|
||||||
|
|
||||||
import { UIBlock } from './block';
|
import { UIBlock } from './block';
|
||||||
|
|
||||||
|
|
@ -6,12 +6,12 @@ import { useState } from 'react';
|
||||||
import { useSWRConfig } from 'swr';
|
import { useSWRConfig } from 'swr';
|
||||||
import { useWindowSize } from 'usehooks-ts';
|
import { useWindowSize } from 'usehooks-ts';
|
||||||
|
|
||||||
import { Document } from '@/db/schema';
|
import { Document } from '@/lib/db/schema';
|
||||||
import { getDocumentTimestampByIndex } from '@/lib/utils';
|
import { getDocumentTimestampByIndex } from '@/lib/utils';
|
||||||
|
|
||||||
import { UIBlock } from './block';
|
import { UIBlock } from './block';
|
||||||
import { LoaderIcon } from './icons';
|
import { LoaderIcon } from './icons';
|
||||||
import { Button } from '../ui/button';
|
import { Button } from './ui/button';
|
||||||
|
|
||||||
interface VersionFooterProps {
|
interface VersionFooterProps {
|
||||||
block: UIBlock;
|
block: UIBlock;
|
||||||
|
|
@ -6,8 +6,8 @@ config({
|
||||||
});
|
});
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
schema: './db/schema.ts',
|
schema: './lib/db/schema.ts',
|
||||||
out: './lib/drizzle',
|
out: './lib/db/migrations',
|
||||||
dialect: 'postgresql',
|
dialect: 'postgresql',
|
||||||
dbCredentials: {
|
dbCredentials: {
|
||||||
url: process.env.POSTGRES_URL!,
|
url: process.env.POSTGRES_URL!,
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import { DOMParser, Node } from 'prosemirror-model';
|
||||||
import { Decoration, DecorationSet, EditorView } from 'prosemirror-view';
|
import { Decoration, DecorationSet, EditorView } from 'prosemirror-view';
|
||||||
import { renderToString } from 'react-dom/server';
|
import { renderToString } from 'react-dom/server';
|
||||||
|
|
||||||
import { Markdown } from '@/components/custom/markdown';
|
import { Markdown } from '@/components/markdown';
|
||||||
|
|
||||||
import { documentSchema } from './config';
|
import { documentSchema } from './config';
|
||||||
import { createSuggestionWidget, UISuggestion } from './suggestions';
|
import { createSuggestionWidget, UISuggestion } from './suggestions';
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ import { PluginKey, Plugin } from 'prosemirror-state';
|
||||||
import { Decoration, DecorationSet, EditorView } from 'prosemirror-view';
|
import { Decoration, DecorationSet, EditorView } from 'prosemirror-view';
|
||||||
import { createRoot } from 'react-dom/client';
|
import { createRoot } from 'react-dom/client';
|
||||||
|
|
||||||
import { Suggestion as PreviewSuggestion } from '@/components/custom/suggestion';
|
import { Suggestion as PreviewSuggestion } from '@/components/suggestion';
|
||||||
import { Suggestion } from '@/db/schema';
|
import { Suggestion } from '@/lib/db/schema';
|
||||||
|
|
||||||
export interface UISuggestion extends Suggestion {
|
export interface UISuggestion extends Suggestion {
|
||||||
selectionStart: number;
|
selectionStart: number;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import {
|
||||||
import { clsx, type ClassValue } from 'clsx';
|
import { clsx, type ClassValue } from 'clsx';
|
||||||
import { twMerge } from 'tailwind-merge';
|
import { twMerge } from 'tailwind-merge';
|
||||||
|
|
||||||
import { Message as DBMessage, Document } from '@/db/schema';
|
import { Message as DBMessage, Document } from '@/lib/db/schema';
|
||||||
|
|
||||||
export function cn(...inputs: ClassValue[]) {
|
export function cn(...inputs: ClassValue[]) {
|
||||||
return twMerge(clsx(inputs));
|
return twMerge(clsx(inputs));
|
||||||
|
|
|
||||||
13
package.json
13
package.json
|
|
@ -4,10 +4,14 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev --turbo",
|
"dev": "next dev --turbo",
|
||||||
"build": "tsx db/migrate && next build",
|
"build": "next build",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "next lint",
|
"lint": "next lint",
|
||||||
"format": "prettier --write ."
|
"lint:fix": "next lint --fix",
|
||||||
|
"format": "biome format --write",
|
||||||
|
"db:generate": "drizzle-kit generate",
|
||||||
|
"db:migrate": "npx tsx lib/db/migrate.ts",
|
||||||
|
"db:studio": "drizzle-kit studio"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ai-sdk/openai": "1.0.0-canary.3",
|
"@ai-sdk/openai": "1.0.0-canary.3",
|
||||||
|
|
@ -62,9 +66,10 @@
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@biomejs/biome": "1.9.4",
|
||||||
"@tailwindcss/typography": "^0.5.15",
|
"@tailwindcss/typography": "^0.5.15",
|
||||||
"@types/d3-scale": "^4.0.8",
|
"@types/d3-scale": "^4.0.8",
|
||||||
"@types/node": "^20",
|
"@types/node": "^22.8.6",
|
||||||
"@types/pdf-parse": "^1.1.4",
|
"@types/pdf-parse": "^1.1.4",
|
||||||
"@types/react": "^18",
|
"@types/react": "^18",
|
||||||
"@types/react-dom": "^18",
|
"@types/react-dom": "^18",
|
||||||
|
|
@ -73,10 +78,8 @@
|
||||||
"eslint-config-next": "14.2.5",
|
"eslint-config-next": "14.2.5",
|
||||||
"eslint-config-prettier": "^9.1.0",
|
"eslint-config-prettier": "^9.1.0",
|
||||||
"eslint-import-resolver-typescript": "^3.6.3",
|
"eslint-import-resolver-typescript": "^3.6.3",
|
||||||
"eslint-plugin-import": "^2.31.0",
|
|
||||||
"eslint-plugin-tailwindcss": "^3.17.5",
|
"eslint-plugin-tailwindcss": "^3.17.5",
|
||||||
"postcss": "^8",
|
"postcss": "^8",
|
||||||
"prettier": "^3.3.3",
|
|
||||||
"tailwindcss": "^3.4.1",
|
"tailwindcss": "^3.4.1",
|
||||||
"tsx": "^4.19.1",
|
"tsx": "^4.19.1",
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
|
|
|
||||||
543
pnpm-lock.yaml
generated
543
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
|
@ -1,9 +0,0 @@
|
||||||
/** @type {import('prettier').Config} */
|
|
||||||
module.exports = {
|
|
||||||
endOfLine: 'lf',
|
|
||||||
semi: true,
|
|
||||||
useTabs: false,
|
|
||||||
singleQuote: true,
|
|
||||||
tabWidth: 2,
|
|
||||||
trailingComma: 'es5',
|
|
||||||
};
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue