refactor: reorganize project structure by moving files to a more dev friendly setup

- Move stores/utils/types to their relative directories (i.e chat stores in chat directory)
- Move utility files to shared/utils
- Move component files to shared/components
- Move type definitions to shared/types
- Move stores to shared/stores
- Update import paths across the project
This commit is contained in:
KevIsDev 2025-06-16 15:33:59 +01:00
parent d0d9818964
commit 4d3222ee96
314 changed files with 1045 additions and 962 deletions

View File

@ -5,34 +5,34 @@
import type { JSONValue, Message } from 'ai';
import React, { type RefCallback, useEffect, useState } from 'react';
import { ClientOnly } from 'remix-utils/client-only';
import { Menu } from '~/components/sidebar/Menu.client';
import { Workbench } from '~/components/workbench/Workbench.client';
import { classNames } from '~/utils/classNames';
import { PROVIDER_LIST } from '~/utils/constants';
import { Menu } from '~/layout/sidebar/Menu.client';
import { Workbench } from '~/shared/workbench/components/Workbench.client';
import { classNames } from '~/shared/utils/classNames';
import { PROVIDER_LIST } from '~/shared/utils/constants';
import { Messages } from './Messages.client';
import { getApiKeysFromCookies } from './APIKeyManager';
import { getApiKeysFromCookies } from './chatBox/APIKeyManager';
import Cookies from 'js-cookie';
import * as Tooltip from '@radix-ui/react-tooltip';
import styles from './BaseChat.module.scss';
import { ImportButtons } from '~/components/chat/chatExportAndImport/ImportButtons';
import { ExamplePrompts } from '~/components/chat/ExamplePrompts';
import GitCloneButton from './GitCloneButton';
import type { ProviderInfo } from '~/types/model';
import { ImportButtons } from '~/chat/components/chatExportAndImport/ImportButtons';
import { ExamplePrompts } from '~/chat/components/ExamplePrompts';
import GitCloneButton from '~/shared/components/github/components/GitCloneButton';
import type { ProviderInfo } from '~/shared/types/model';
import StarterTemplates from './StarterTemplates';
import type { ActionAlert, SupabaseAlert, DeployAlert } from '~/types/actions';
import DeployChatAlert from '~/components/deploy/DeployAlert';
import ChatAlert from './ChatAlert';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { ActionAlert, SupabaseAlert, DeployAlert } from '~/shared/types/actions';
import DeployChatAlert from '~/chat/components/alerts/DeployAlert';
import ChatAlert from './alerts/ChatAlert';
import type { ModelInfo } from '~/shared/lib/providers/types';
import ProgressCompilation from './ProgressCompilation';
import type { ProgressAnnotation } from '~/types/context';
import type { ActionRunner } from '~/lib/runtime/action-runner';
import { SupabaseChatAlert } from '~/components/chat/SupabaseAlert';
import { expoUrlAtom } from '~/lib/stores/qrCodeStore';
import type { ProgressAnnotation } from '~/shared/types/context';
import type { ActionRunner } from '~/shared/lib/runtime/action-runner';
import { SupabaseChatAlert } from '~/chat/components/alerts/SupabaseAlert';
import { expoUrlAtom } from '~/shared/workbench/stores/qrCodeStore';
import { useStore } from '@nanostores/react';
import { StickToBottom, useStickToBottomContext } from '~/lib/hooks';
import { ChatBox } from './ChatBox';
import type { DesignScheme } from '~/types/design-scheme';
import type { ElementInfo } from '~/components/workbench/Inspector';
import { StickToBottom, useStickToBottomContext } from '~/chat/hooks/StickToBottom';
import { ChatBox } from './chatBox/ChatBox';
import type { DesignScheme } from '~/shared/types/design-scheme';
import type { ElementInfo } from '~/shared/workbench/components/ui/Inspector';
const TEXTAREA_MIN_HEIGHT = 76;

View File

@ -8,27 +8,27 @@ import { useChat } from 'ai/react';
import { useAnimate } from 'framer-motion';
import { memo, useCallback, useEffect, useRef, useState } from 'react';
import { cssTransition, toast, ToastContainer } from 'react-toastify';
import { useMessageParser, usePromptEnhancer, useShortcuts } from '~/lib/hooks';
import { description, useChatHistory } from '~/lib/persistence';
import { chatStore } from '~/lib/stores/chat';
import { workbenchStore } from '~/lib/stores/workbench';
import { DEFAULT_MODEL, DEFAULT_PROVIDER, PROMPT_COOKIE_KEY, PROVIDER_LIST } from '~/utils/constants';
import { cubicEasingFn } from '~/utils/easings';
import { createScopedLogger, renderLogger } from '~/utils/logger';
import { useMessageParser, usePromptEnhancer, useShortcuts } from '~/shared/hooks';
import { description, useChatHistory } from '~/shared/lib/persistence';
import { chatStore } from '~/chat/stores/chat';
import { workbenchStore } from '~/shared/workbench/stores/workbench';
import { DEFAULT_MODEL, DEFAULT_PROVIDER, PROMPT_COOKIE_KEY, PROVIDER_LIST } from '~/shared/utils/constants';
import { cubicEasingFn } from '~/shared/utils/easings';
import { createScopedLogger, renderLogger } from '~/shared/utils/logger';
import { BaseChat } from './BaseChat';
import Cookies from 'js-cookie';
import { debounce } from '~/utils/debounce';
import { useSettings } from '~/lib/hooks/useSettings';
import type { ProviderInfo } from '~/types/model';
import { debounce } from '~/shared/utils/debounce';
import { useSettings } from '~/shared/hooks/useSettings';
import type { ProviderInfo } from '~/shared/types/model';
import { useSearchParams } from '@remix-run/react';
import { createSampler } from '~/utils/sampler';
import { getTemplates, selectStarterTemplate } from '~/utils/selectStarterTemplate';
import { logStore } from '~/lib/stores/logs';
import { streamingState } from '~/lib/stores/streaming';
import { filesToArtifacts } from '~/utils/fileUtils';
import { supabaseConnection } from '~/lib/stores/supabase';
import { defaultDesignScheme, type DesignScheme } from '~/types/design-scheme';
import type { ElementInfo } from '~/components/workbench/Inspector';
import { createSampler } from '~/shared/utils/sampler';
import { getTemplates, selectStarterTemplate } from '~/shared/utils/selectStarterTemplate';
import { logStore } from '~/shared/stores/logs';
import { streamingState } from '~/shared/stores/streaming';
import { filesToArtifacts } from '~/shared/utils/fileUtils';
import { supabaseConnection } from '~/shared/stores/supabase';
import { defaultDesignScheme, type DesignScheme } from '~/shared/types/design-scheme';
import type { ElementInfo } from '~/shared/workbench/components/ui/Inspector';
const toastAnimation = cssTransition({
enter: 'animated fadeInRight',

View File

@ -1,15 +1,15 @@
import type { Message } from 'ai';
import { Fragment } from 'react';
import { classNames } from '~/utils/classNames';
import { AssistantMessage } from './AssistantMessage';
import { UserMessage } from './UserMessage';
import { classNames } from '~/shared/utils/classNames';
import { AssistantMessage } from './messages/AssistantMessage';
import { UserMessage } from './messages/UserMessage';
import { useLocation } from '@remix-run/react';
import { db, chatId } from '~/lib/persistence/useChatHistory';
import { forkChat } from '~/lib/persistence/db';
import { db, chatId } from '~/shared/lib/persistence/useChatHistory';
import { forkChat } from '~/shared/lib/persistence/db';
import { toast } from 'react-toastify';
import { forwardRef } from 'react';
import type { ForwardedRef } from 'react';
import type { ProviderInfo } from '~/types/model';
import type { ProviderInfo } from '~/shared/types/model';
interface MessagesProps {
id?: string;

View File

@ -1,8 +1,8 @@
import { AnimatePresence, motion } from 'framer-motion';
import React, { useState } from 'react';
import type { ProgressAnnotation } from '~/types/context';
import { classNames } from '~/utils/classNames';
import { cubicEasingFn } from '~/utils/easings';
import type { ProgressAnnotation } from '~/shared/types/context';
import { classNames } from '~/shared/utils/classNames';
import { cubicEasingFn } from '~/shared/utils/easings';
export default function ProgressCompilation({ data }: { data?: ProgressAnnotation[] }) {
const [progressList, setProgressList] = React.useState<ProgressAnnotation[]>([]);

View File

@ -1,6 +1,6 @@
import React from 'react';
import type { Template } from '~/types/template';
import { STARTER_TEMPLATES } from '~/utils/constants';
import type { Template } from '~/shared/types/template';
import { STARTER_TEMPLATES } from '~/shared/utils/constants';
interface FrameworkLinkProps {
template: Template;

View File

@ -1,6 +1,6 @@
import { AnimatePresence, motion } from 'framer-motion';
import type { ActionAlert } from '~/types/actions';
import { classNames } from '~/utils/classNames';
import type { ActionAlert } from '~/shared/types/actions';
import { classNames } from '~/shared/utils/classNames';
interface Props {
alert: ActionAlert;

View File

@ -1,6 +1,6 @@
import { AnimatePresence, motion } from 'framer-motion';
import { classNames } from '~/utils/classNames';
import type { DeployAlert } from '~/types/actions';
import { classNames } from '~/shared/utils/classNames';
import type { DeployAlert } from '~/shared/types/actions';
interface DeployAlertProps {
alert: DeployAlert;

View File

@ -1,7 +1,7 @@
import { AnimatePresence, motion } from 'framer-motion';
import type { SupabaseAlert } from '~/types/actions';
import { classNames } from '~/utils/classNames';
import { supabaseConnection } from '~/lib/stores/supabase';
import type { SupabaseAlert } from '~/shared/types/actions';
import { classNames } from '~/shared/utils/classNames';
import { supabaseConnection } from '~/shared/stores/supabase';
import { useStore } from '@nanostores/react';
import { useState } from 'react';

View File

@ -1,6 +1,6 @@
import React, { useState, useEffect, useCallback } from 'react';
import { IconButton } from '~/components/ui/IconButton';
import type { ProviderInfo } from '~/types/model';
import { IconButton } from '~/shared/components/ui/IconButton';
import type { ProviderInfo } from '~/shared/types/model';
import Cookies from 'js-cookie';
interface APIKeyManagerProps {

View File

@ -1,23 +1,23 @@
import React from 'react';
import { ClientOnly } from 'remix-utils/client-only';
import { classNames } from '~/utils/classNames';
import { PROVIDER_LIST } from '~/utils/constants';
import { ModelSelector } from '~/components/chat/ModelSelector';
import { classNames } from '~/shared/utils/classNames';
import { PROVIDER_LIST } from '~/shared/utils/constants';
import { ModelSelector } from '~/chat/components/chatBox/ModelSelector';
import { APIKeyManager } from './APIKeyManager';
import { LOCAL_PROVIDERS } from '~/lib/stores/settings';
import { LOCAL_PROVIDERS } from '~/settings/stores/settings';
import FilePreview from './FilePreview';
import { ScreenshotStateManager } from './ScreenshotStateManager';
import { SendButton } from './SendButton.client';
import { IconButton } from '~/components/ui/IconButton';
import { IconButton } from '~/shared/components/ui/IconButton';
import { toast } from 'react-toastify';
import { SpeechRecognitionButton } from '~/components/chat/SpeechRecognition';
import { SpeechRecognitionButton } from '~/chat/components/chatBox/SpeechRecognition';
import { SupabaseConnection } from './SupabaseConnection';
import { ExpoQrModal } from '~/components/workbench/ExpoQrModal';
import styles from './BaseChat.module.scss';
import type { ProviderInfo } from '~/types/model';
import { ColorSchemeDialog } from '~/components/ui/ColorSchemeDialog';
import type { DesignScheme } from '~/types/design-scheme';
import type { ElementInfo } from '~/components/workbench/Inspector';
import { ExpoQrModal } from '~/shared/workbench/components/ui/ExpoQrModal';
import styles from '~/chat/BaseChat.module.scss';
import type { ProviderInfo } from '~/shared/types/model';
import { ColorSchemeDialog } from '~/shared/components/ui/ColorSchemeDialog';
import type { DesignScheme } from '~/shared/types/design-scheme';
import type { ElementInfo } from '~/shared/workbench/components/ui/Inspector';
interface ChatBoxProps {
isModelSettingsCollapsed: boolean;

View File

@ -1,5 +1,5 @@
import { classNames } from '~/utils/classNames';
import { IconButton } from '~/components/ui';
import { classNames } from '~/shared/utils/classNames';
import { IconButton } from '~/shared/components/ui';
export function DiscussMode() {
return (

View File

@ -1,8 +1,8 @@
import type { ProviderInfo } from '~/types/model';
import type { ProviderInfo } from '~/shared/types/model';
import { useEffect, useState, useRef } from 'react';
import type { KeyboardEvent } from 'react';
import type { ModelInfo } from '~/lib/modules/llm/types';
import { classNames } from '~/utils/classNames';
import type { ModelInfo } from '~/shared/lib/providers/types';
import { classNames } from '~/shared/utils/classNames';
interface ModelSelectorProps {
model?: string;

View File

@ -1,5 +1,5 @@
import { IconButton } from '~/components/ui/IconButton';
import { classNames } from '~/utils/classNames';
import { IconButton } from '~/shared/components/ui/IconButton';
import { classNames } from '~/shared/utils/classNames';
import React from 'react';
export const SpeechRecognitionButton = ({

View File

@ -1,10 +1,10 @@
import { useEffect } from 'react';
import { useSupabaseConnection } from '~/lib/hooks/useSupabaseConnection';
import { classNames } from '~/utils/classNames';
import { useSupabaseConnection } from '~/shared/hooks/useSupabaseConnection';
import { classNames } from '~/shared/utils/classNames';
import { useStore } from '@nanostores/react';
import { chatId } from '~/lib/persistence/useChatHistory';
import { fetchSupabaseStats } from '~/lib/stores/supabase';
import { Dialog, DialogRoot, DialogClose, DialogTitle, DialogButton } from '~/components/ui/Dialog';
import { chatId } from '~/shared/lib/persistence/useChatHistory';
import { fetchSupabaseStats } from '~/shared/stores/supabase';
import { Dialog, DialogRoot, DialogClose, DialogTitle, DialogButton } from '~/shared/components/ui/Dialog';
export function SupabaseConnection() {
const {

View File

@ -1,6 +1,6 @@
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
import { workbenchStore } from '~/lib/stores/workbench';
import { classNames } from '~/utils/classNames';
import { workbenchStore } from '~/shared/workbench/stores/workbench';
import { classNames } from '~/shared/utils/classNames';
export const ExportChatButton = ({ exportChat }: { exportChat?: () => void }) => {
return (

View File

@ -1,8 +1,8 @@
import type { Message } from 'ai';
import { toast } from 'react-toastify';
import { ImportFolderButton } from '~/components/chat/ImportFolderButton';
import { Button } from '~/components/ui/Button';
import { classNames } from '~/utils/classNames';
import { ImportFolderButton } from '~/chat/components/chatExportAndImport/ImportFolderButton';
import { Button } from '~/shared/components/ui/Button';
import { classNames } from '~/shared/utils/classNames';
type ChatData = {
messages?: Message[]; // Standard Bolt format

View File

@ -1,11 +1,11 @@
import React, { useState } from 'react';
import type { Message } from 'ai';
import { toast } from 'react-toastify';
import { MAX_FILES, isBinaryFile, shouldIncludeFile } from '~/utils/fileUtils';
import { createChatFromFolder } from '~/utils/folderImport';
import { logStore } from '~/lib/stores/logs'; // Assuming logStore is imported from this location
import { Button } from '~/components/ui/Button';
import { classNames } from '~/utils/classNames';
import { MAX_FILES, isBinaryFile, shouldIncludeFile } from '~/shared/utils/fileUtils';
import { createChatFromFolder } from '~/shared/utils/folderImport';
import { logStore } from '~/shared/stores/logs'; // Assuming logStore is imported from this location
import { Button } from '~/shared/components/ui/Button';
import { classNames } from '~/shared/utils/classNames';
interface ImportFolderButtonProps {
className?: string;

View File

@ -1,14 +1,14 @@
import { memo, useMemo } from 'react';
import ReactMarkdown, { type Components } from 'react-markdown';
import type { BundledLanguage } from 'shiki';
import { createScopedLogger } from '~/utils/logger';
import { rehypePlugins, remarkPlugins, allowedHTMLElements } from '~/utils/markdown';
import { Artifact, openArtifactInWorkbench } from './Artifact';
import { CodeBlock } from './CodeBlock';
import { createScopedLogger } from '~/shared/utils/logger';
import { rehypePlugins, remarkPlugins, allowedHTMLElements } from '~/shared/utils/markdown';
import { Artifact, openArtifactInWorkbench } from '~/chat/components/messages/Artifact';
import { CodeBlock } from '~/chat/components/messages/CodeBlock';
import type { Message } from 'ai';
import styles from './Markdown.module.scss';
import ThoughtBox from './ThoughtBox';
import type { ProviderInfo } from '~/types/model';
import ThoughtBox from '~/chat/components/ThoughtBox';
import type { ProviderInfo } from '~/shared/types/model';
const logger = createScopedLogger('MarkdownComponent');

View File

@ -3,11 +3,11 @@ import { AnimatePresence, motion } from 'framer-motion';
import { computed } from 'nanostores';
import { memo, useEffect, useRef, useState } from 'react';
import { createHighlighter, type BundledLanguage, type BundledTheme, type HighlighterGeneric } from 'shiki';
import type { ActionState } from '~/lib/runtime/action-runner';
import { workbenchStore } from '~/lib/stores/workbench';
import { classNames } from '~/utils/classNames';
import { cubicEasingFn } from '~/utils/easings';
import { WORK_DIR } from '~/utils/constants';
import type { ActionState } from '~/shared/lib/runtime/action-runner';
import { workbenchStore } from '~/shared/workbench/stores/workbench';
import { classNames } from '~/shared/utils/classNames';
import { cubicEasingFn } from '~/shared/utils/easings';
import { WORK_DIR } from '~/shared/utils/constants';
const highlighterOptions = {
langs: ['shell'],

View File

@ -1,12 +1,12 @@
import { memo, Fragment } from 'react';
import { Markdown } from './Markdown';
import { Markdown } from '~/chat/components/markdown/Markdown';
import type { JSONValue } from 'ai';
import Popover from '~/components/ui/Popover';
import { workbenchStore } from '~/lib/stores/workbench';
import { WORK_DIR } from '~/utils/constants';
import WithTooltip from '~/components/ui/Tooltip';
import Popover from '~/shared/components/ui/Popover';
import { workbenchStore } from '~/shared/workbench/stores/workbench';
import { WORK_DIR } from '~/shared/utils/constants';
import WithTooltip from '~/shared/components/ui/Tooltip';
import type { Message } from 'ai';
import type { ProviderInfo } from '~/types/model';
import type { ProviderInfo } from '~/shared/types/model';
interface AssistantMessageProps {
content: string;

View File

@ -1,7 +1,7 @@
import { memo, useEffect, useState } from 'react';
import { bundledLanguages, codeToHtml, isSpecialLang, type BundledLanguage, type SpecialLanguage } from 'shiki';
import { classNames } from '~/utils/classNames';
import { createScopedLogger } from '~/utils/logger';
import { classNames } from '~/shared/utils/classNames';
import { createScopedLogger } from '~/shared/utils/logger';
import styles from './CodeBlock.module.scss';

View File

@ -2,10 +2,10 @@
* @ts-nocheck
* Preventing TS checks with files presented in the video for a better presentation.
*/
import { MODEL_REGEX, PROVIDER_REGEX } from '~/utils/constants';
import { Markdown } from './Markdown';
import { MODEL_REGEX, PROVIDER_REGEX } from '~/shared/utils/constants';
import { Markdown } from '~/chat/components/markdown/Markdown';
import { useStore } from '@nanostores/react';
import { profileStore } from '~/lib/stores/profile';
import { profileStore } from '~/shared/stores/profile';
interface UserMessageProps {
content: string | Array<{ type: string; text?: string; image?: string }>;

View File

@ -1,6 +1,6 @@
import { useState } from 'react';
import type { ProviderInfo } from '~/types/model';
import { createScopedLogger } from '~/utils/logger';
import type { ProviderInfo } from '~/shared/types/model';
import { createScopedLogger } from '~/shared/utils/logger';
const logger = createScopedLogger('usePromptEnhancement');

View File

@ -1,6 +1,6 @@
import Cookies from 'js-cookie';
import { type Message } from 'ai';
import { getAllChats, deleteChat } from '~/lib/persistence/chats';
import { getAllChats, deleteChat } from '~/shared/lib/persistence/chats';
interface ExtendedMessage extends Message {
name?: string;

View File

@ -4,7 +4,7 @@ import { isbot } from 'isbot';
import { renderToReadableStream } from 'react-dom/server';
import { renderHeadToString } from 'remix-island';
import { Head } from './root';
import { themeStore } from '~/lib/stores/theme';
import { themeStore } from '~/shared/stores/theme';
export default async function handleRequest(
request: Request,

View File

@ -1,15 +1,15 @@
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
import { useStore } from '@nanostores/react';
import { netlifyConnection } from '~/lib/stores/netlify';
import { vercelConnection } from '~/lib/stores/vercel';
import { workbenchStore } from '~/lib/stores/workbench';
import { streamingState } from '~/lib/stores/streaming';
import { classNames } from '~/utils/classNames';
import { netlifyConnection } from '~/shared/stores/netlify';
import { vercelConnection } from '~/shared/stores/vercel';
import { workbenchStore } from '~/shared/workbench/stores/workbench';
import { streamingState } from '~/shared/stores/streaming';
import { classNames } from '~/shared/utils/classNames';
import { useState } from 'react';
import { NetlifyDeploymentLink } from '~/components/chat/NetlifyDeploymentLink.client';
import { VercelDeploymentLink } from '~/components/chat/VercelDeploymentLink.client';
import { useVercelDeploy } from '~/components/deploy/VercelDeploy.client';
import { useNetlifyDeploy } from '~/components/deploy/NetlifyDeploy.client';
import { NetlifyDeploymentLink } from '~/layout/header/components/NetlifyDeploymentLink.client';
import { VercelDeploymentLink } from '~/layout/header/components/VercelDeploymentLink.client';
import { useVercelDeploy } from '~/layout/header/hooks/useVercelDeploy';
import { useNetlifyDeploy } from '~/layout/header/hooks/useNetlifyDeploy';
interface DeployButtonProps {
onVercelDeploy?: () => Promise<void>;

View File

@ -1,9 +1,9 @@
import { useStore } from '@nanostores/react';
import { ClientOnly } from 'remix-utils/client-only';
import { chatStore } from '~/lib/stores/chat';
import { classNames } from '~/utils/classNames';
import { chatStore } from '~/chat/stores/chat';
import { classNames } from '~/shared/utils/classNames';
import { HeaderActionButtons } from './HeaderActionButtons.client';
import { ChatDescription } from '~/lib/persistence/ChatDescription.client';
import { ChatDescription } from '~/shared/lib/persistence/ChatDescription.client';
export function Header() {
const chat = useStore(chatStore);

View File

@ -1,10 +1,10 @@
import { useStore } from '@nanostores/react';
import { workbenchStore } from '~/lib/stores/workbench';
import { workbenchStore } from '~/shared/workbench/stores/workbench';
import { useState } from 'react';
import { streamingState } from '~/lib/stores/streaming';
import { ExportChatButton } from '~/components/chat/chatExportAndImport/ExportChatButton';
import { useChatHistory } from '~/lib/persistence';
import { DeployButton } from '~/components/deploy/DeployButton';
import { streamingState } from '~/shared/stores/streaming';
import { ExportChatButton } from '~/chat/components/chatExportAndImport/ExportChatButton';
import { useChatHistory } from '~/shared/lib/persistence';
import { DeployButton } from '~/layout/header/components/DeployButton';
interface HeaderActionButtonsProps {
chatStarted: boolean;

View File

@ -1,6 +1,6 @@
import { useStore } from '@nanostores/react';
import { netlifyConnection, fetchNetlifyStats } from '~/lib/stores/netlify';
import { chatId } from '~/lib/persistence/useChatHistory';
import { netlifyConnection, fetchNetlifyStats } from '~/shared/stores/netlify';
import { chatId } from '~/shared/lib/persistence/useChatHistory';
import * as Tooltip from '@radix-ui/react-tooltip';
import { useEffect } from 'react';

View File

@ -1,6 +1,6 @@
import { useStore } from '@nanostores/react';
import { vercelConnection } from '~/lib/stores/vercel';
import { chatId } from '~/lib/persistence/useChatHistory';
import { vercelConnection } from '~/shared/stores/vercel';
import { chatId } from '~/shared/lib/persistence/useChatHistory';
import * as Tooltip from '@radix-ui/react-tooltip';
import { useEffect, useState } from 'react';

View File

@ -7,7 +7,7 @@ import {
description as descriptionStore,
getMessages,
updateChatDescription,
} from '~/lib/persistence';
} from '~/shared/lib/persistence';
interface EditChatDescriptionOptions {
initialDescription?: string;

View File

@ -1,12 +1,12 @@
import { toast } from 'react-toastify';
import { useStore } from '@nanostores/react';
import { netlifyConnection } from '~/lib/stores/netlify';
import { workbenchStore } from '~/lib/stores/workbench';
import { webcontainer } from '~/lib/webcontainer';
import { path } from '~/utils/path';
import { netlifyConnection } from '~/shared/stores/netlify';
import { workbenchStore } from '~/shared/workbench/stores/workbench';
import { webcontainer } from '~/shared/lib/webcontainer';
import { path } from '~/shared/utils/path';
import { useState } from 'react';
import type { ActionCallbackData } from '~/lib/runtime/message-parser';
import { chatId } from '~/lib/persistence/useChatHistory';
import type { ActionCallbackData } from '~/shared/lib/runtime/message-parser';
import { chatId } from '~/shared/lib/persistence/useChatHistory';
export function useNetlifyDeploy() {
const [isDeploying, setIsDeploying] = useState(false);

View File

@ -1,12 +1,12 @@
import { toast } from 'react-toastify';
import { useStore } from '@nanostores/react';
import { vercelConnection } from '~/lib/stores/vercel';
import { workbenchStore } from '~/lib/stores/workbench';
import { webcontainer } from '~/lib/webcontainer';
import { path } from '~/utils/path';
import { vercelConnection } from '~/shared/stores/vercel';
import { workbenchStore } from '~/shared/workbench/stores/workbench';
import { webcontainer } from '~/shared/lib/webcontainer';
import { path } from '~/shared/utils/path';
import { useState } from 'react';
import type { ActionCallbackData } from '~/lib/runtime/message-parser';
import { chatId } from '~/lib/persistence/useChatHistory';
import type { ActionCallbackData } from '~/shared/lib/runtime/message-parser';
import { chatId } from '~/shared/lib/persistence/useChatHistory';
export function useVercelDeploy() {
const [isDeploying, setIsDeploying] = useState(false);

View File

@ -1,10 +1,10 @@
import { useParams } from '@remix-run/react';
import { classNames } from '~/utils/classNames';
import { type ChatHistoryItem } from '~/lib/persistence';
import WithTooltip from '~/components/ui/Tooltip';
import { useEditChatDescription } from '~/lib/hooks';
import { classNames } from '~/shared/utils/classNames';
import { type ChatHistoryItem } from '~/shared/lib/persistence';
import WithTooltip from '~/shared/components/ui/Tooltip';
import { useEditChatDescription } from '~/shared/hooks';
import { forwardRef, type ForwardedRef, useCallback } from 'react';
import { Checkbox } from '~/components/ui/Checkbox';
import { Checkbox } from '~/shared/components/ui/Checkbox';
interface HistoryItemProps {
item: ChatHistoryItem;

View File

@ -1,19 +1,19 @@
import { motion, type Variants } from 'framer-motion';
import { useCallback, useEffect, useRef, useState } from 'react';
import { toast } from 'react-toastify';
import { Dialog, DialogButton, DialogDescription, DialogRoot, DialogTitle } from '~/components/ui/Dialog';
import { ThemeSwitch } from '~/components/ui/ThemeSwitch';
import { ControlPanel } from '~/components/@settings/core/ControlPanel';
import { SettingsButton } from '~/components/ui/SettingsButton';
import { Button } from '~/components/ui/Button';
import { db, deleteById, getAll, chatId, type ChatHistoryItem, useChatHistory } from '~/lib/persistence';
import { cubicEasingFn } from '~/utils/easings';
import { Dialog, DialogButton, DialogDescription, DialogRoot, DialogTitle } from '~/shared/components/ui/Dialog';
import { ThemeSwitch } from '~/shared/components/ui/ThemeSwitch';
import { ControlPanel } from '~/settings/core/ControlPanel';
import { SettingsButton } from '~/shared/components/ui/SettingsButton';
import { Button } from '~/shared/components/ui/Button';
import { db, deleteById, getAll, chatId, type ChatHistoryItem, useChatHistory } from '~/shared/lib/persistence';
import { cubicEasingFn } from '~/shared/utils/easings';
import { HistoryItem } from './HistoryItem';
import { binDates } from './date-binning';
import { useSearchFilter } from '~/lib/hooks/useSearchFilter';
import { classNames } from '~/utils/classNames';
import { useSearchFilter } from '~/shared/hooks/useSearchFilter';
import { classNames } from '~/shared/utils/classNames';
import { useStore } from '@nanostores/react';
import { profileStore } from '~/lib/stores/profile';
import { profileStore } from '~/shared/stores/profile';
const menuVariants = {
closed: {

View File

@ -1,5 +1,5 @@
import { format, isAfter, isThisWeek, isThisYear, isToday, isYesterday, subDays } from 'date-fns';
import type { ChatHistoryItem } from '~/lib/persistence';
import type { ChatHistoryItem } from '~/shared/lib/persistence';
type Bin = { category: string; items: ChatHistoryItem[] };

View File

@ -1,207 +0,0 @@
import { convertToCoreMessages, streamText as _streamText, type Message } from 'ai';
import { MAX_TOKENS, type FileMap } from './constants';
import { getSystemPrompt } from '~/lib/common/prompts/prompts';
import { DEFAULT_MODEL, DEFAULT_PROVIDER, MODIFICATIONS_TAG_NAME, PROVIDER_LIST, WORK_DIR } from '~/utils/constants';
import type { IProviderSetting } from '~/types/model';
import { PromptLibrary } from '~/lib/common/prompt-library';
import { allowedHTMLElements } from '~/utils/markdown';
import { LLMManager } from '~/lib/modules/llm/manager';
import { createScopedLogger } from '~/utils/logger';
import { createFilesContext, extractPropertiesFromMessage } from './utils';
import { discussPrompt } from '~/lib/common/prompts/discuss-prompt';
import type { DesignScheme } from '~/types/design-scheme';
export type Messages = Message[];
export interface StreamingOptions extends Omit<Parameters<typeof _streamText>[0], 'model'> {
supabaseConnection?: {
isConnected: boolean;
hasSelectedProject: boolean;
credentials?: {
anonKey?: string;
supabaseUrl?: string;
};
};
}
const logger = createScopedLogger('stream-text');
export async function streamText(props: {
messages: Omit<Message, 'id'>[];
env?: Env;
options?: StreamingOptions;
apiKeys?: Record<string, string>;
files?: FileMap;
providerSettings?: Record<string, IProviderSetting>;
promptId?: string;
contextOptimization?: boolean;
contextFiles?: FileMap;
summary?: string;
messageSliceId?: number;
chatMode?: 'discuss' | 'build';
designScheme?: DesignScheme;
}) {
const {
messages,
env: serverEnv,
options,
apiKeys,
files,
providerSettings,
promptId,
contextOptimization,
contextFiles,
summary,
chatMode,
designScheme,
} = props;
let currentModel = DEFAULT_MODEL;
let currentProvider = DEFAULT_PROVIDER.name;
let processedMessages = messages.map((message) => {
if (message.role === 'user') {
const { model, provider, content } = extractPropertiesFromMessage(message);
currentModel = model;
currentProvider = provider;
return { ...message, content };
} else if (message.role == 'assistant') {
let content = message.content;
content = content.replace(/<div class=\\"__boltThought__\\">.*?<\/div>/s, '');
content = content.replace(/<think>.*?<\/think>/s, '');
// Remove package-lock.json content specifically keeping token usage MUCH lower
content = content.replace(
/<boltAction type="file" filePath="package-lock\.json">[\s\S]*?<\/boltAction>/g,
'[package-lock.json content removed]',
);
// Trim whitespace potentially left after removals
content = content.trim();
return { ...message, content };
}
return message;
});
const provider = PROVIDER_LIST.find((p) => p.name === currentProvider) || DEFAULT_PROVIDER;
const staticModels = LLMManager.getInstance().getStaticModelListFromProvider(provider);
let modelDetails = staticModels.find((m) => m.name === currentModel);
if (!modelDetails) {
const modelsList = [
...(provider.staticModels || []),
...(await LLMManager.getInstance().getModelListFromProvider(provider, {
apiKeys,
providerSettings,
serverEnv: serverEnv as any,
})),
];
if (!modelsList.length) {
throw new Error(`No models found for provider ${provider.name}`);
}
modelDetails = modelsList.find((m) => m.name === currentModel);
if (!modelDetails) {
// Fallback to first model
logger.warn(
`MODEL [${currentModel}] not found in provider [${provider.name}]. Falling back to first model. ${modelsList[0].name}`,
);
modelDetails = modelsList[0];
}
}
const dynamicMaxTokens = modelDetails && modelDetails.maxTokenAllowed ? modelDetails.maxTokenAllowed : MAX_TOKENS;
logger.info(
`Max tokens for model ${modelDetails.name} is ${dynamicMaxTokens} based on ${modelDetails.maxTokenAllowed} or ${MAX_TOKENS}`,
);
let systemPrompt =
PromptLibrary.getPropmtFromLibrary(promptId || 'default', {
cwd: WORK_DIR,
allowedHtmlElements: allowedHTMLElements,
modificationTagName: MODIFICATIONS_TAG_NAME,
designScheme,
supabase: {
isConnected: options?.supabaseConnection?.isConnected || false,
hasSelectedProject: options?.supabaseConnection?.hasSelectedProject || false,
credentials: options?.supabaseConnection?.credentials || undefined,
},
}) ?? getSystemPrompt();
if (chatMode === 'build' && contextFiles && contextOptimization) {
const codeContext = createFilesContext(contextFiles, true);
systemPrompt = `${systemPrompt}
Below is the artifact containing the context loaded into context buffer for you to have knowledge of and might need changes to fullfill current user request.
CONTEXT BUFFER:
---
${codeContext}
---
`;
if (summary) {
systemPrompt = `${systemPrompt}
below is the chat history till now
CHAT SUMMARY:
---
${props.summary}
---
`;
if (props.messageSliceId) {
processedMessages = processedMessages.slice(props.messageSliceId);
} else {
const lastMessage = processedMessages.pop();
if (lastMessage) {
processedMessages = [lastMessage];
}
}
}
}
const effectiveLockedFilePaths = new Set<string>();
if (files) {
for (const [filePath, fileDetails] of Object.entries(files)) {
if (fileDetails?.isLocked) {
effectiveLockedFilePaths.add(filePath);
}
}
}
if (effectiveLockedFilePaths.size > 0) {
const lockedFilesListString = Array.from(effectiveLockedFilePaths)
.map((filePath) => `- ${filePath}`)
.join('\n');
systemPrompt = `${systemPrompt}
IMPORTANT: The following files are locked and MUST NOT be modified in any way. Do not suggest or make any changes to these files. You can proceed with the request but DO NOT make any changes to these files specifically:
${lockedFilesListString}
---
`;
} else {
console.log('No locked files found from any source for prompt.');
}
logger.info(`Sending llm call to ${provider.name} with model ${modelDetails.name}`);
// console.log(systemPrompt, processedMessages);
return await _streamText({
model: provider.getModelInstance({
model: modelDetails.name,
serverEnv,
apiKeys,
providerSettings,
}),
system: chatMode === 'build' ? systemPrompt : discussPrompt(),
maxTokens: dynamicMaxTokens,
messages: convertToCoreMessages(processedMessages as any),
...options,
});
}

View File

@ -1,39 +0,0 @@
import AnthropicProvider from './providers/anthropic';
import CohereProvider from './providers/cohere';
import DeepseekProvider from './providers/deepseek';
import GoogleProvider from './providers/google';
import GroqProvider from './providers/groq';
import HuggingFaceProvider from './providers/huggingface';
import LMStudioProvider from './providers/lmstudio';
import MistralProvider from './providers/mistral';
import OllamaProvider from './providers/ollama';
import OpenRouterProvider from './providers/open-router';
import OpenAILikeProvider from './providers/openai-like';
import OpenAIProvider from './providers/openai';
import PerplexityProvider from './providers/perplexity';
import TogetherProvider from './providers/together';
import XAIProvider from './providers/xai';
import HyperbolicProvider from './providers/hyperbolic';
import AmazonBedrockProvider from './providers/amazon-bedrock';
import GithubProvider from './providers/github';
export {
AnthropicProvider,
CohereProvider,
DeepseekProvider,
GoogleProvider,
GroqProvider,
HuggingFaceProvider,
HyperbolicProvider,
MistralProvider,
OllamaProvider,
OpenAIProvider,
OpenRouterProvider,
OpenAILikeProvider,
PerplexityProvider,
XAIProvider,
TogetherProvider,
LMStudioProvider,
AmazonBedrockProvider,
GithubProvider,
};

View File

@ -2,8 +2,8 @@ import { useStore } from '@nanostores/react';
import type { LinksFunction } from '@remix-run/cloudflare';
import { Links, Meta, Outlet, Scripts, ScrollRestoration } from '@remix-run/react';
import tailwindReset from '@unocss/reset/tailwind-compat.css?url';
import { themeStore } from './lib/stores/theme';
import { stripIndents } from './utils/stripIndent';
import { themeStore } from './shared/stores/theme';
import { stripIndents } from './shared/utils/stripIndent';
import { createHead } from 'remix-island';
import { useEffect } from 'react';
import { DndProvider } from 'react-dnd';
@ -81,7 +81,7 @@ export function Layout({ children }: { children: React.ReactNode }) {
);
}
import { logStore } from './lib/stores/logs';
import { logStore } from './shared/stores/logs';
export default function App() {
const theme = useStore(themeStore);

View File

@ -1,9 +1,9 @@
import { json, type MetaFunction } from '@remix-run/cloudflare';
import { ClientOnly } from 'remix-utils/client-only';
import { BaseChat } from '~/components/chat/BaseChat';
import { Chat } from '~/components/chat/Chat.client';
import { Header } from '~/components/header/Header';
import BackgroundRays from '~/components/ui/BackgroundRays';
import { BaseChat } from '~/chat/components/BaseChat';
import { Chat } from '~/chat/components/Chat.client';
import { Header } from '~/layout/header/components/Header';
import BackgroundRays from '~/shared/components/ui/BackgroundRays';
export const meta: MetaFunction = () => {
return [{ title: 'Bolt' }, { name: 'description', content: 'Talk with Bolt, an AI assistant from StackBlitz' }];

View File

@ -1,17 +1,17 @@
import { type ActionFunctionArgs } from '@remix-run/cloudflare';
import { createDataStream, generateId } from 'ai';
import { MAX_RESPONSE_SEGMENTS, MAX_TOKENS, type FileMap } from '~/lib/.server/llm/constants';
import { CONTINUE_PROMPT } from '~/lib/common/prompts/prompts';
import { streamText, type Messages, type StreamingOptions } from '~/lib/.server/llm/stream-text';
import SwitchableStream from '~/lib/.server/llm/switchable-stream';
import type { IProviderSetting } from '~/types/model';
import { createScopedLogger } from '~/utils/logger';
import { getFilePaths, selectContext } from '~/lib/.server/llm/select-context';
import type { ContextAnnotation, ProgressAnnotation } from '~/types/context';
import { WORK_DIR } from '~/utils/constants';
import { createSummary } from '~/lib/.server/llm/create-summary';
import { extractPropertiesFromMessage } from '~/lib/.server/llm/utils';
import type { DesignScheme } from '~/types/design-scheme';
import { MAX_RESPONSE_SEGMENTS, MAX_TOKENS, type FileMap } from '~/shared/lib/.server/llm/constants';
import { CONTINUE_PROMPT } from '~/shared/lib/prompts/prompt-variants/prompts';
import { streamText, type Messages, type StreamingOptions } from '~/shared/lib/.server/llm/stream-text';
import SwitchableStream from '~/shared/lib/.server/llm/switchable-stream';
import type { IProviderSetting } from '~/shared/types/model';
import { createScopedLogger } from '~/shared/utils/logger';
import { getFilePaths, selectContext } from '~/shared/lib/.server/llm/select-context';
import type { ContextAnnotation, ProgressAnnotation } from '~/shared/types/context';
import { WORK_DIR } from '~/shared/utils/constants';
import { createSummary } from '~/shared/lib/.server/llm/create-summary';
import { extractPropertiesFromMessage } from '~/shared/lib/.server/llm/utils';
import type { DesignScheme } from '~/shared/types/design-scheme';
export async function action(args: ActionFunctionArgs) {
return chatAction(args);

View File

@ -1,6 +1,6 @@
import type { LoaderFunction } from '@remix-run/cloudflare';
import { LLMManager } from '~/lib/modules/llm/manager';
import { getApiKeysFromCookie } from '~/lib/api/cookies';
import { LLMManager } from '~/shared/lib/providers/manager';
import { getApiKeysFromCookie } from '~/shared/lib/api/cookies';
export const loader: LoaderFunction = async ({ context, request }) => {
const url = new URL(request.url);

View File

@ -1,9 +1,9 @@
import { type ActionFunctionArgs } from '@remix-run/cloudflare';
import { streamText } from '~/lib/.server/llm/stream-text';
import { stripIndents } from '~/utils/stripIndent';
import type { ProviderInfo } from '~/types/model';
import { getApiKeysFromCookie, getProviderSettingsFromCookie } from '~/lib/api/cookies';
import { createScopedLogger } from '~/utils/logger';
import { streamText } from '~/shared/lib/.server/llm/stream-text';
import { stripIndents } from '~/shared/utils/stripIndent';
import type { ProviderInfo } from '~/shared/types/model';
import { getApiKeysFromCookie, getProviderSettingsFromCookie } from '~/shared/lib/api/cookies';
import { createScopedLogger } from '~/shared/utils/logger';
export async function action(args: ActionFunctionArgs) {
return enhancerAction(args);

View File

@ -1,6 +1,6 @@
import type { LoaderFunction } from '@remix-run/cloudflare';
import { LLMManager } from '~/lib/modules/llm/manager';
import { getApiKeysFromCookie } from '~/lib/api/cookies';
import { LLMManager } from '~/shared/lib/providers/manager';
import { getApiKeysFromCookie } from '~/shared/lib/api/cookies';
export const loader: LoaderFunction = async ({ context, request }) => {
// Get API keys from cookie

View File

@ -1,13 +1,13 @@
import { type ActionFunctionArgs } from '@remix-run/cloudflare';
import { streamText } from '~/lib/.server/llm/stream-text';
import type { IProviderSetting, ProviderInfo } from '~/types/model';
import { streamText } from '~/shared/lib/.server/llm/stream-text';
import type { IProviderSetting, ProviderInfo } from '~/shared/types/model';
import { generateText } from 'ai';
import { PROVIDER_LIST } from '~/utils/constants';
import { MAX_TOKENS } from '~/lib/.server/llm/constants';
import { LLMManager } from '~/lib/modules/llm/manager';
import type { ModelInfo } from '~/lib/modules/llm/types';
import { getApiKeysFromCookie, getProviderSettingsFromCookie } from '~/lib/api/cookies';
import { createScopedLogger } from '~/utils/logger';
import { PROVIDER_LIST } from '~/shared/utils/constants';
import { MAX_TOKENS } from '~/shared/lib/.server/llm/constants';
import { LLMManager } from '~/shared/lib/providers/manager';
import type { ModelInfo } from '~/shared/lib/providers/types';
import { getApiKeysFromCookie, getProviderSettingsFromCookie } from '~/shared/lib/api/cookies';
import { createScopedLogger } from '~/shared/utils/logger';
export async function action(args: ActionFunctionArgs) {
return llmCallAction(args);

View File

@ -1,8 +1,8 @@
import { json } from '@remix-run/cloudflare';
import { LLMManager } from '~/lib/modules/llm/manager';
import type { ModelInfo } from '~/lib/modules/llm/types';
import type { ProviderInfo } from '~/types/model';
import { getApiKeysFromCookie, getProviderSettingsFromCookie } from '~/lib/api/cookies';
import { LLMManager } from '~/shared/lib/providers/manager';
import type { ModelInfo } from '~/shared/lib/providers/types';
import type { ProviderInfo } from '~/shared/types/model';
import { getApiKeysFromCookie, getProviderSettingsFromCookie } from '~/shared/lib/api/cookies';
interface ModelsResponse {
modelList: ModelInfo[];

View File

@ -1,6 +1,6 @@
import { type ActionFunctionArgs, json } from '@remix-run/cloudflare';
import crypto from 'crypto';
import type { NetlifySiteInfo } from '~/types/netlify';
import type { NetlifySiteInfo } from '~/shared/types/netlify';
interface DeployRequestBody {
siteId?: string;

View File

@ -1,5 +1,5 @@
import { type ActionFunctionArgs } from '@remix-run/cloudflare';
import { createScopedLogger } from '~/utils/logger';
import { createScopedLogger } from '~/shared/utils/logger';
const logger = createScopedLogger('api.supabase.query');

View File

@ -1,5 +1,5 @@
import { json, type ActionFunction } from '@remix-run/cloudflare';
import type { SupabaseProject } from '~/types/supabase';
import type { SupabaseProject } from '~/shared/types/supabase';
export const action: ActionFunction = async ({ request }) => {
if (request.method !== 'POST') {

View File

@ -1,5 +1,5 @@
import { type ActionFunctionArgs, type LoaderFunctionArgs, json } from '@remix-run/cloudflare';
import type { VercelProjectInfo } from '~/types/vercel';
import type { VercelProjectInfo } from '~/shared/types/vercel';
// Add loader function to handle GET requests
export async function loader({ request }: LoaderFunctionArgs) {

View File

@ -1,10 +1,10 @@
import type { LoaderFunctionArgs } from '@remix-run/cloudflare';
import { json, type MetaFunction } from '@remix-run/cloudflare';
import { ClientOnly } from 'remix-utils/client-only';
import { BaseChat } from '~/components/chat/BaseChat';
import { GitUrlImport } from '~/components/git/GitUrlImport.client';
import { Header } from '~/components/header/Header';
import BackgroundRays from '~/components/ui/BackgroundRays';
import { BaseChat } from '~/chat/components/BaseChat';
import { GitUrlImport } from '~/shared/components/github/components/GitUrlImport.client';
import { Header } from '~/layout/header/components/Header';
import BackgroundRays from '~/shared/components/ui/BackgroundRays';
export const meta: MetaFunction = () => {
return [{ title: 'Bolt' }, { name: 'description', content: 'Talk with Bolt, an AI assistant from StackBlitz' }];

View File

@ -1,8 +1,8 @@
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
import { motion } from 'framer-motion';
import { useStore } from '@nanostores/react';
import { classNames } from '~/utils/classNames';
import { profileStore } from '~/lib/stores/profile';
import { classNames } from '~/shared/utils/classNames';
import { profileStore } from '~/shared/stores/profile';
import type { TabType, Profile } from './types';
const BetaLabel = () => (

View File

@ -3,41 +3,41 @@ import { motion, AnimatePresence } from 'framer-motion';
import { useStore } from '@nanostores/react';
import { Switch } from '@radix-ui/react-switch';
import * as RadixDialog from '@radix-ui/react-dialog';
import { classNames } from '~/utils/classNames';
import { TabManagement } from '~/components/@settings/shared/components/TabManagement';
import { TabTile } from '~/components/@settings/shared/components/TabTile';
import { useUpdateCheck } from '~/lib/hooks/useUpdateCheck';
import { useFeatures } from '~/lib/hooks/useFeatures';
import { useNotifications } from '~/lib/hooks/useNotifications';
import { useConnectionStatus } from '~/lib/hooks/useConnectionStatus';
import { useDebugStatus } from '~/lib/hooks/useDebugStatus';
import { classNames } from '~/shared/utils/classNames';
import { TabManagement } from '~/settings/shared/components/TabManagement';
import { TabTile } from '~/settings/shared/components/TabTile';
import { useUpdateCheck } from '~/shared/hooks/useUpdateCheck';
import { useFeatures } from '~/shared/hooks/useFeatures';
import { useNotifications } from '~/shared/hooks/useNotifications';
import { useConnectionStatus } from '~/shared/hooks/useConnectionStatus';
import { useDebugStatus } from '~/shared/hooks/useDebugStatus';
import {
tabConfigurationStore,
developerModeStore,
setDeveloperMode,
resetTabConfiguration,
} from '~/lib/stores/settings';
import { profileStore } from '~/lib/stores/profile';
} from '~/settings/stores/settings';
import { profileStore } from '~/shared/stores/profile';
import type { TabType, TabVisibilityConfig, Profile } from './types';
import { TAB_LABELS, DEFAULT_TAB_CONFIG } from './constants';
import { DialogTitle } from '~/components/ui/Dialog';
import { DialogTitle } from '~/shared/components/ui/Dialog';
import { AvatarDropdown } from './AvatarDropdown';
import BackgroundRays from '~/components/ui/BackgroundRays';
import BackgroundRays from '~/shared/components/ui/BackgroundRays';
// Import all tab components
import ProfileTab from '~/components/@settings/tabs/profile/ProfileTab';
import SettingsTab from '~/components/@settings/tabs/settings/SettingsTab';
import NotificationsTab from '~/components/@settings/tabs/notifications/NotificationsTab';
import FeaturesTab from '~/components/@settings/tabs/features/FeaturesTab';
import { DataTab } from '~/components/@settings/tabs/data/DataTab';
import DebugTab from '~/components/@settings/tabs/debug/DebugTab';
import { EventLogsTab } from '~/components/@settings/tabs/event-logs/EventLogsTab';
import UpdateTab from '~/components/@settings/tabs/update/UpdateTab';
import ConnectionsTab from '~/components/@settings/tabs/connections/ConnectionsTab';
import CloudProvidersTab from '~/components/@settings/tabs/providers/cloud/CloudProvidersTab';
import ServiceStatusTab from '~/components/@settings/tabs/providers/status/ServiceStatusTab';
import LocalProvidersTab from '~/components/@settings/tabs/providers/local/LocalProvidersTab';
import TaskManagerTab from '~/components/@settings/tabs/task-manager/TaskManagerTab';
import ProfileTab from '~/settings/tabs/profile/ProfileTab';
import SettingsTab from '~/settings/tabs/settings/SettingsTab';
import NotificationsTab from '~/settings/tabs/notifications/NotificationsTab';
import FeaturesTab from '~/settings/tabs/features/FeaturesTab';
import { DataTab } from '~/settings/tabs/data/DataTab';
import DebugTab from '~/settings/tabs/debug/DebugTab';
import { EventLogsTab } from '~/settings/tabs/event-logs/EventLogsTab';
import UpdateTab from '~/settings/tabs/update/UpdateTab';
import ConnectionsTab from '~/settings/tabs/connections/ConnectionsTab';
import CloudProvidersTab from '~/settings/tabs/providers/cloud/CloudProvidersTab';
import ServiceStatusTab from '~/settings/tabs/providers/status/ServiceStatusTab';
import LocalProvidersTab from '~/settings/tabs/providers/local/LocalProvidersTab';
import TaskManagerTab from '~/settings/tabs/task-manager/TaskManagerTab';
interface ControlPanelProps {
open: boolean;

View File

@ -1,9 +1,9 @@
import { useDrag, useDrop } from 'react-dnd';
import { motion } from 'framer-motion';
import { classNames } from '~/utils/classNames';
import type { TabVisibilityConfig } from '~/components/@settings/core/types';
import { TAB_LABELS } from '~/components/@settings/core/types';
import { Switch } from '~/components/ui/Switch';
import { classNames } from '~/shared/utils/classNames';
import type { TabVisibilityConfig } from '~/settings/core/types';
import { TAB_LABELS } from '~/settings/core/types';
import { Switch } from '~/shared/components/ui/Switch';
interface DraggableTabListProps {
tabs: TabVisibilityConfig[];

View File

@ -1,14 +1,14 @@
import { useState, useEffect } from 'react';
import { motion } from 'framer-motion';
import { useStore } from '@nanostores/react';
import { Switch } from '~/components/ui/Switch';
import { classNames } from '~/utils/classNames';
import { tabConfigurationStore } from '~/lib/stores/settings';
import { TAB_LABELS } from '~/components/@settings/core/constants';
import type { TabType } from '~/components/@settings/core/types';
import { Switch } from '~/shared/components/ui/Switch';
import { classNames } from '~/shared/utils/classNames';
import { tabConfigurationStore } from '~/settings/stores/settings';
import { TAB_LABELS } from '~/settings/core/constants';
import type { TabType } from '~/settings/core/types';
import { toast } from 'react-toastify';
import { TbLayoutGrid } from 'react-icons/tb';
import { useSettingsStore } from '~/lib/stores/settings';
import { useSettingsStore } from '~/settings/stores/settings';
// Define tab icons mapping
const TAB_ICONS: Record<TabType, string> = {

View File

@ -1,8 +1,8 @@
import { motion } from 'framer-motion';
import * as Tooltip from '@radix-ui/react-tooltip';
import { classNames } from '~/utils/classNames';
import type { TabVisibilityConfig } from '~/components/@settings/core/types';
import { TAB_LABELS, TAB_ICONS } from '~/components/@settings/core/constants';
import { classNames } from '~/shared/utils/classNames';
import type { TabVisibilityConfig } from '~/settings/core/types';
import { TAB_LABELS, TAB_ICONS } from '~/settings/core/constants';
interface TabTileProps {
tab: TabVisibilityConfig;

View File

@ -1,15 +1,10 @@
import { atom, map } from 'nanostores';
import { PROVIDER_LIST } from '~/utils/constants';
import type { IProviderConfig } from '~/types/model';
import type {
TabVisibilityConfig,
TabWindowConfig,
UserTabConfig,
DevTabConfig,
} from '~/components/@settings/core/types';
import { DEFAULT_TAB_CONFIG } from '~/components/@settings/core/constants';
import { PROVIDER_LIST } from '~/shared/utils/constants';
import type { IProviderConfig } from '~/shared/types/model';
import type { TabVisibilityConfig, TabWindowConfig, UserTabConfig, DevTabConfig } from '~/settings/core/types';
import { DEFAULT_TAB_CONFIG } from '~/settings/core/constants';
import Cookies from 'js-cookie';
import { toggleTheme } from './theme';
import { toggleTheme } from '~/shared/stores/theme';
import { create } from 'zustand';
export interface Shortcut {

View File

@ -1,9 +1,9 @@
import React, { useState } from 'react';
import { toast } from 'react-toastify';
import { Button } from '~/components/ui/Button';
import { Badge } from '~/components/ui/Badge';
import { classNames } from '~/utils/classNames';
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '~/components/ui/Collapsible';
import { Button } from '~/shared/components/ui/Button';
import { Badge } from '~/shared/components/ui/Badge';
import { classNames } from '~/shared/utils/classNames';
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '~/shared/components/ui/Collapsible';
import { CodeBracketIcon, ChevronDownIcon } from '@heroicons/react/24/outline';
// Helper function to safely parse JSON

View File

@ -1,8 +1,8 @@
import { motion } from 'framer-motion';
import React, { Suspense, useState } from 'react';
import { classNames } from '~/utils/classNames';
import { classNames } from '~/shared/utils/classNames';
import ConnectionDiagnostics from './ConnectionDiagnostics';
import { Button } from '~/components/ui/Button';
import { Button } from '~/shared/components/ui/Button';
import VercelConnection from './VercelConnection';
// Use React.lazy for dynamic imports

View File

@ -1,11 +1,11 @@
import React, { useState, useEffect } from 'react';
import { motion } from 'framer-motion';
import { toast } from 'react-toastify';
import { logStore } from '~/lib/stores/logs';
import { classNames } from '~/utils/classNames';
import { logStore } from '~/shared/stores/logs';
import { classNames } from '~/shared/utils/classNames';
import Cookies from 'js-cookie';
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '~/components/ui/Collapsible';
import { Button } from '~/components/ui/Button';
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '~/shared/components/ui/Collapsible';
import { Button } from '~/shared/components/ui/Button';
interface GitHubUserResponse {
login: string;

View File

@ -1,9 +1,9 @@
import React, { useState, useEffect } from 'react';
import { toast } from 'react-toastify';
import { classNames } from '~/utils/classNames';
import { classNames } from '~/shared/utils/classNames';
import { useStore } from '@nanostores/react';
import { netlifyConnection, updateNetlifyConnection, initializeNetlifyConnection } from '~/lib/stores/netlify';
import type { NetlifySite, NetlifyDeploy, NetlifyBuild, NetlifyUser } from '~/types/netlify';
import { netlifyConnection, updateNetlifyConnection, initializeNetlifyConnection } from '~/shared/stores/netlify';
import type { NetlifySite, NetlifyDeploy, NetlifyBuild, NetlifyUser } from '~/shared/types/netlify';
import {
CloudIcon,
BuildingLibraryIcon,
@ -17,10 +17,10 @@ import {
LockOpenIcon,
RocketLaunchIcon,
} from '@heroicons/react/24/outline';
import { Button } from '~/components/ui/Button';
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '~/components/ui/Collapsible';
import { Button } from '~/shared/components/ui/Button';
import { Collapsible, CollapsibleTrigger, CollapsibleContent } from '~/shared/components/ui/Collapsible';
import { formatDistanceToNow } from 'date-fns';
import { Badge } from '~/components/ui/Badge';
import { Badge } from '~/shared/components/ui/Badge';
// Add the Netlify logo SVG component at the top of the file
const NetlifyLogo = () => (

View File

@ -2,15 +2,15 @@ import React, { useEffect, useState } from 'react';
import { motion } from 'framer-motion';
import { toast } from 'react-toastify';
import { useStore } from '@nanostores/react';
import { logStore } from '~/lib/stores/logs';
import { classNames } from '~/utils/classNames';
import { logStore } from '~/shared/stores/logs';
import { classNames } from '~/shared/utils/classNames';
import {
vercelConnection,
isConnecting,
isFetchingStats,
updateVercelConnection,
fetchVercelStats,
} from '~/lib/stores/vercel';
} from '~/shared/stores/vercel';
export default function VercelConnection() {
const connection = useStore(vercelConnection);

View File

@ -1,8 +1,8 @@
import React, { useEffect } from 'react';
import { classNames } from '~/utils/classNames';
import type { GitHubAuthState } from '~/components/@settings/tabs/connections/types/GitHub';
import { classNames } from '~/shared/utils/classNames';
import type { GitHubAuthState } from '~/settings/tabs/connections/types/GitHub';
import Cookies from 'js-cookie';
import { getLocalStorage } from '~/lib/persistence';
import { getLocalStorage } from '~/shared/lib/persistence';
const GITHUB_TOKEN_KEY = 'github_token';

View File

@ -1,7 +1,7 @@
import { useState } from 'react';
import * as Dialog from '@radix-ui/react-dialog';
import { classNames } from '~/utils/classNames';
import type { GitHubRepoInfo } from '~/components/@settings/tabs/connections/types/GitHub';
import { classNames } from '~/shared/utils/classNames';
import type { GitHubRepoInfo } from '~/settings/tabs/connections/types/GitHub';
import { GitBranch } from '@phosphor-icons/react';
interface GitHubBranch {

View File

@ -3,7 +3,7 @@ import * as Dialog from '@radix-ui/react-dialog';
import { motion } from 'framer-motion';
import { toast } from 'react-toastify';
import Cookies from 'js-cookie';
import type { GitHubUserResponse } from '~/types/GitHub';
import type { GitHubUserResponse } from '~/shared/components/github/types/GitHub';
interface GitHubAuthDialogProps {
isOpen: boolean;

View File

@ -5,17 +5,17 @@ import { motion } from 'framer-motion';
import { Octokit } from '@octokit/rest';
// Internal imports
import { getLocalStorage } from '~/lib/persistence';
import { classNames } from '~/utils/classNames';
import type { GitHubUserResponse } from '~/types/GitHub';
import { logStore } from '~/lib/stores/logs';
import { workbenchStore } from '~/lib/stores/workbench';
import { extractRelativePath } from '~/utils/diff';
import { formatSize } from '~/utils/formatSize';
import type { FileMap, File } from '~/lib/stores/files';
import { getLocalStorage } from '~/shared/lib/persistence';
import { classNames } from '~/shared/utils/classNames';
import type { GitHubUserResponse } from '~/shared/components/github/types/GitHub';
import { logStore } from '~/shared/stores/logs';
import { workbenchStore } from '~/shared/workbench/stores/workbench';
import { extractRelativePath } from '~/shared/utils/diff';
import { formatSize } from '~/shared/utils/formatSize';
import type { FileMap, File } from '~/shared/workbench/stores/files';
// UI Components
import { Badge, EmptyState, StatusIndicator, SearchInput } from '~/components/ui';
import { Badge, EmptyState, StatusIndicator, SearchInput } from '~/shared/components/ui';
interface PushToGitHubDialogProps {
isOpen: boolean;

View File

@ -1,6 +1,6 @@
import React from 'react';
import { motion } from 'framer-motion';
import type { GitHubRepoInfo } from '~/types/GitHub';
import type { GitHubRepoInfo } from '~/shared/components/github/types/GitHub';
interface RepositoryCardProps {
repo: GitHubRepoInfo;

View File

@ -1,6 +1,6 @@
import React, { useContext } from 'react';
import type { GitHubRepoInfo } from '~/types/GitHub';
import { EmptyState, StatusIndicator } from '~/components/ui';
import type { GitHubRepoInfo } from '~/shared/components/github/types/GitHub';
import { EmptyState, StatusIndicator } from '~/shared/components/ui';
import { RepositoryCard } from './RepositoryCard';
import { RepositoryDialogContext } from './RepositoryDialogContext';

View File

@ -1,14 +1,19 @@
import type { GitHubRepoInfo, GitHubContent, RepositoryStats, GitHubUserResponse } from '~/types/GitHub';
import type {
GitHubRepoInfo,
GitHubContent,
RepositoryStats,
GitHubUserResponse,
} from '~/shared/components/github/types/GitHub';
import { useState, useEffect } from 'react';
import { toast } from 'react-toastify';
import * as Dialog from '@radix-ui/react-dialog';
import { classNames } from '~/utils/classNames';
import { getLocalStorage } from '~/lib/persistence';
import { classNames } from '~/shared/utils/classNames';
import { getLocalStorage } from '~/shared/lib/persistence';
import { motion, AnimatePresence } from 'framer-motion';
import Cookies from 'js-cookie';
// Import UI components
import { Input, SearchInput, Badge, FilterChip } from '~/components/ui';
import { Input, SearchInput, Badge, FilterChip } from '~/shared/components/ui';
// Import the components we've extracted
import { RepositoryList } from './RepositoryList';

View File

@ -1,9 +1,9 @@
import React from 'react';
import * as Dialog from '@radix-ui/react-dialog';
import { motion } from 'framer-motion';
import type { RepositoryStats } from '~/types/GitHub';
import { formatSize } from '~/utils/formatSize';
import { RepositoryStats as RepoStats } from '~/components/ui';
import type { RepositoryStats } from '~/shared/components/github/types/GitHub';
import { formatSize } from '~/shared/utils/formatSize';
import { RepositoryStats as RepoStats } from '~/shared/components/ui';
interface StatsDialogProps {
isOpen: boolean;

View File

@ -1,13 +1,13 @@
import { useState, useRef, useCallback, useEffect } from 'react';
import { Button } from '~/components/ui/Button';
import { ConfirmationDialog, SelectionDialog } from '~/components/ui/Dialog';
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '~/components/ui/Card';
import { Button } from '~/shared/components/ui/Button';
import { ConfirmationDialog, SelectionDialog } from '~/shared/components/ui/Dialog';
import { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter } from '~/shared/components/ui/Card';
import { motion } from 'framer-motion';
import { useDataOperations } from '~/lib/hooks/useDataOperations';
import { openDatabase } from '~/lib/persistence/db';
import { getAllChats, type Chat } from '~/lib/persistence/chats';
import { useDataOperations } from '~/shared/hooks/useDataOperations';
import { openDatabase } from '~/shared/lib/persistence/db';
import { getAllChats, type Chat } from '~/shared/lib/persistence/chats';
import { DataVisualization } from './DataVisualization';
import { classNames } from '~/utils/classNames';
import { classNames } from '~/shared/utils/classNames';
import { toast } from 'react-toastify';
// Create a custom hook to connect to the boltHistory database

View File

@ -12,8 +12,8 @@ import {
LineElement,
} from 'chart.js';
import { Bar, Pie } from 'react-chartjs-2';
import type { Chat } from '~/lib/persistence/chats';
import { classNames } from '~/utils/classNames';
import type { Chat } from '~/shared/lib/persistence/chats';
import { classNames } from '~/shared/utils/classNames';
// Register ChartJS components
ChartJS.register(CategoryScale, LinearScale, BarElement, Title, Tooltip, Legend, ArcElement, PointElement, LineElement);

View File

@ -1,15 +1,15 @@
import React, { useEffect, useState, useMemo, useCallback } from 'react';
import { toast } from 'react-toastify';
import { classNames } from '~/utils/classNames';
import { logStore, type LogEntry } from '~/lib/stores/logs';
import { classNames } from '~/shared/utils/classNames';
import { logStore, type LogEntry } from '~/shared/stores/logs';
import { useStore } from '@nanostores/react';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '~/components/ui/Collapsible';
import { Progress } from '~/components/ui/Progress';
import { ScrollArea } from '~/components/ui/ScrollArea';
import { Badge } from '~/components/ui/Badge';
import { Dialog, DialogRoot, DialogTitle } from '~/components/ui/Dialog';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '~/shared/components/ui/Collapsible';
import { Progress } from '~/shared/components/ui/Progress';
import { ScrollArea } from '~/shared/components/ui/ScrollArea';
import { Badge } from '~/shared/components/ui/Badge';
import { Dialog, DialogRoot, DialogTitle } from '~/shared/components/ui/Dialog';
import { jsPDF } from 'jspdf';
import { useSettings } from '~/lib/hooks/useSettings';
import { useSettings } from '~/shared/hooks/useSettings';
interface SystemInfo {
os: string;

View File

@ -1,11 +1,11 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { motion } from 'framer-motion';
import { Switch } from '~/components/ui/Switch';
import { logStore, type LogEntry } from '~/lib/stores/logs';
import { Switch } from '~/shared/components/ui/Switch';
import { logStore, type LogEntry } from '~/shared/stores/logs';
import { useStore } from '@nanostores/react';
import { classNames } from '~/utils/classNames';
import { classNames } from '~/shared/utils/classNames';
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
import { Dialog, DialogRoot, DialogTitle } from '~/components/ui/Dialog';
import { Dialog, DialogRoot, DialogTitle } from '~/shared/components/ui/Dialog';
import { jsPDF } from 'jspdf';
import { toast } from 'react-toastify';

View File

@ -1,11 +1,11 @@
// Remove unused imports
import React, { memo, useCallback } from 'react';
import { motion } from 'framer-motion';
import { Switch } from '~/components/ui/Switch';
import { useSettings } from '~/lib/hooks/useSettings';
import { classNames } from '~/utils/classNames';
import { Switch } from '~/shared/components/ui/Switch';
import { useSettings } from '~/shared/hooks/useSettings';
import { classNames } from '~/shared/utils/classNames';
import { toast } from 'react-toastify';
import { PromptLibrary } from '~/lib/common/prompt-library';
import { PromptLibrary } from '~/shared/lib/prompts/prompt-library';
interface FeatureToggle {
id: string;

View File

@ -1,9 +1,9 @@
import React, { useState, useEffect } from 'react';
import { motion } from 'framer-motion';
import { logStore } from '~/lib/stores/logs';
import { logStore } from '~/shared/stores/logs';
import { useStore } from '@nanostores/react';
import { formatDistanceToNow } from 'date-fns';
import { classNames } from '~/utils/classNames';
import { classNames } from '~/shared/utils/classNames';
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
interface NotificationDetails {

View File

@ -1,9 +1,9 @@
import { useState, useCallback } from 'react';
import { useStore } from '@nanostores/react';
import { classNames } from '~/utils/classNames';
import { profileStore, updateProfile } from '~/lib/stores/profile';
import { classNames } from '~/shared/utils/classNames';
import { profileStore, updateProfile } from '~/shared/stores/profile';
import { toast } from 'react-toastify';
import { debounce } from '~/utils/debounce';
import { debounce } from '~/shared/utils/debounce';
export default function ProfileTab() {
const profile = useStore(profileStore);

View File

@ -1,13 +1,13 @@
import React, { useEffect, useState, useCallback } from 'react';
import { Switch } from '~/components/ui/Switch';
import { useSettings } from '~/lib/hooks/useSettings';
import { URL_CONFIGURABLE_PROVIDERS } from '~/lib/stores/settings';
import type { IProviderConfig } from '~/types/model';
import { logStore } from '~/lib/stores/logs';
import { Switch } from '~/shared/components/ui/Switch';
import { useSettings } from '~/shared/hooks/useSettings';
import { URL_CONFIGURABLE_PROVIDERS } from '~/settings/stores/settings';
import type { IProviderConfig } from '~/shared/types/model';
import { logStore } from '~/shared/stores/logs';
import { motion } from 'framer-motion';
import { classNames } from '~/utils/classNames';
import { classNames } from '~/shared/utils/classNames';
import { toast } from 'react-toastify';
import { providerBaseUrlEnvKeys } from '~/utils/constants';
import { providerBaseUrlEnvKeys } from '~/shared/utils/constants';
import { SiAmazon, SiGoogle, SiHuggingface, SiPerplexity, SiOpenai } from 'react-icons/si';
import { BsRobot, BsCloud } from 'react-icons/bs';
import { TbBrain, TbCloudComputing } from 'react-icons/tb';

View File

@ -1,18 +1,18 @@
import React, { useEffect, useState, useCallback } from 'react';
import { Switch } from '~/components/ui/Switch';
import { useSettings } from '~/lib/hooks/useSettings';
import { LOCAL_PROVIDERS, URL_CONFIGURABLE_PROVIDERS } from '~/lib/stores/settings';
import type { IProviderConfig } from '~/types/model';
import { logStore } from '~/lib/stores/logs';
import { Switch } from '~/shared/components/ui/Switch';
import { useSettings } from '~/shared/hooks/useSettings';
import { LOCAL_PROVIDERS, URL_CONFIGURABLE_PROVIDERS } from '~/settings/stores/settings';
import type { IProviderConfig } from '~/shared/types/model';
import { logStore } from '~/shared/stores/logs';
import { motion, AnimatePresence } from 'framer-motion';
import { classNames } from '~/utils/classNames';
import { classNames } from '~/shared/utils/classNames';
import { BsRobot } from 'react-icons/bs';
import type { IconType } from 'react-icons';
import { BiChip } from 'react-icons/bi';
import { TbBrandOpenai } from 'react-icons/tb';
import { providerBaseUrlEnvKeys } from '~/utils/constants';
import { useToast } from '~/components/ui/use-toast';
import { Progress } from '~/components/ui/Progress';
import { providerBaseUrlEnvKeys } from '~/shared/utils/constants';
import { useToast } from '~/shared/components/ui/use-toast';
import { Progress } from '~/shared/components/ui/Progress';
import OllamaModelInstaller from './OllamaModelInstaller';
// Add type for provider names to ensure type safety

View File

@ -1,9 +1,9 @@
import React, { useState, useEffect } from 'react';
import { motion } from 'framer-motion';
import { classNames } from '~/utils/classNames';
import { Progress } from '~/components/ui/Progress';
import { useToast } from '~/components/ui/use-toast';
import { useSettings } from '~/lib/hooks/useSettings';
import { classNames } from '~/shared/utils/classNames';
import { Progress } from '~/shared/components/ui/Progress';
import { useToast } from '~/shared/components/ui/use-toast';
import { useSettings } from '~/shared/hooks/useSettings';
interface OllamaModelInstallerProps {
onModelInstalled: () => void;

Some files were not shown because too many files have changed in this diff Show More