feat: keyboard navigation; improvement: SEO/GEO; refactor: file structure, unused fonts; fix: chat streaming, notification stack (#2083)

* improvement: panel tabs handler on click

* fix: output break words

* feat: keyboard navigation; improvement: SEO/GEO; refactor: file structure, unused fonts; fix: chat streaming, notification stack

* feat: unresolved value handling on error; fix: layout refresh; refactor: delete old panel

* refactor: control bar delete; improvement: workflow constants; fix: clear notifications keyboard shortcut

* update developers count

* fixed relative imports

---------

Co-authored-by: waleed <walif6@gmail.com>
This commit is contained in:
Emir Karabeg
2025-11-20 19:37:09 -08:00
committed by GitHub
parent 6187561219
commit 3dbf0f5679
486 changed files with 2180 additions and 6956 deletions

View File

@@ -374,7 +374,7 @@ In addition, you will need to update the registries:
Add your block to the blocks registry (`/apps/sim/blocks/registry.ts`):
```typescript:/apps/sim/blocks/registry.ts
import { PineconeBlock } from './blocks/pinecone'
import { PineconeBlock } from '@/blocks/blocks/pinecone'
// Registry of all available blocks
export const registry: Record<string, BlockConfig> = {

View File

@@ -1,7 +1,7 @@
'use client'
import type * as React from 'react'
import { blockTypeToIconMap } from './icon-mapping'
import { blockTypeToIconMap } from '@/components/ui/icon-mapping'
interface BlockInfoCardProps {
type: string

View File

@@ -2,8 +2,8 @@
import { useState } from 'react'
import NextImage, { type ImageProps as NextImageProps } from 'next/image'
import { Lightbox } from '@/components/ui/lightbox'
import { cn } from '@/lib/utils'
import { Lightbox } from './lightbox'
interface ImageProps extends Omit<NextImageProps, 'className'> {
className?: string

View File

@@ -1,5 +1,5 @@
import { cn } from '@/lib/utils'
import AuthBackgroundSVG from './auth-background-svg'
import AuthBackgroundSVG from '@/app/(auth)/components/auth-background-svg'
type AuthBackgroundProps = {
className?: string

View File

@@ -4,7 +4,7 @@ import { type ReactNode, useEffect, useState } from 'react'
import { GithubIcon, GoogleIcon } from '@/components/icons'
import { Button } from '@/components/ui/button'
import { client } from '@/lib/auth-client'
import { inter } from '@/app/fonts/inter/inter'
import { inter } from '@/app/_styles/fonts/inter/inter'
interface SocialLoginButtonsProps {
githubAvailable: boolean

View File

@@ -1,8 +1,8 @@
'use client'
import { useEffect } from 'react'
import AuthBackground from '@/app/(auth)/components/auth-background'
import Nav from '@/app/(landing)/components/nav/nav'
import AuthBackground from './components/auth-background'
// Helper to detect if a color is dark
function isColorDark(hexColor: string): boolean {

View File

@@ -20,10 +20,10 @@ import { getEnv, isFalsy, isTruthy } from '@/lib/env'
import { createLogger } from '@/lib/logs/console/logger'
import { getBaseUrl } from '@/lib/urls/utils'
import { cn } from '@/lib/utils'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import { SocialLoginButtons } from '@/app/(auth)/components/social-login-buttons'
import { SSOLoginButton } from '@/app/(auth)/components/sso-login-button'
import { inter } from '@/app/fonts/inter/inter'
import { soehne } from '@/app/fonts/soehne/soehne'
const logger = createLogger('LoginForm')

View File

@@ -4,9 +4,9 @@ import { Suspense, useEffect, useState } from 'react'
import Link from 'next/link'
import { useRouter, useSearchParams } from 'next/navigation'
import { createLogger } from '@/lib/logs/console/logger'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import { SetNewPasswordForm } from '@/app/(auth)/reset-password/reset-password-form'
import { inter } from '@/app/fonts/inter/inter'
import { soehne } from '@/app/fonts/soehne/soehne'
const logger = createLogger('ResetPasswordPage')

View File

@@ -6,7 +6,7 @@ import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { cn } from '@/lib/utils'
import { inter } from '@/app/fonts/inter/inter'
import { inter } from '@/app/_styles/fonts/inter/inter'
interface RequestResetFormProps {
email: string

View File

@@ -12,10 +12,10 @@ import { quickValidateEmail } from '@/lib/email/validation'
import { getEnv, isFalsy, isTruthy } from '@/lib/env'
import { createLogger } from '@/lib/logs/console/logger'
import { cn } from '@/lib/utils'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import { SocialLoginButtons } from '@/app/(auth)/components/social-login-buttons'
import { SSOLoginButton } from '@/app/(auth)/components/sso-login-button'
import { inter } from '@/app/fonts/inter/inter'
import { soehne } from '@/app/fonts/soehne/soehne'
const logger = createLogger('SignupForm')

View File

@@ -1,6 +1,6 @@
import { redirect } from 'next/navigation'
import { getEnv, isTruthy } from '@/lib/env'
import SSOForm from './sso-form'
import SSOForm from '@/app/(auth)/sso/sso-form'
export const dynamic = 'force-dynamic'

View File

@@ -11,8 +11,8 @@ import { quickValidateEmail } from '@/lib/email/validation'
import { env, isFalsy } from '@/lib/env'
import { createLogger } from '@/lib/logs/console/logger'
import { cn } from '@/lib/utils'
import { inter } from '@/app/fonts/inter/inter'
import { soehne } from '@/app/fonts/soehne/soehne'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
const logger = createLogger('SSOForm')

View File

@@ -5,9 +5,9 @@ import { useRouter } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { InputOTP, InputOTPGroup, InputOTPSlot } from '@/components/ui/input-otp'
import { cn } from '@/lib/utils'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import { useVerification } from '@/app/(auth)/verify/use-verification'
import { inter } from '@/app/fonts/inter/inter'
import { soehne } from '@/app/fonts/soehne/soehne'
interface VerifyContentProps {
hasEmailService: boolean

View File

@@ -17,9 +17,9 @@ import { quickValidateEmail } from '@/lib/email/validation'
import { isHosted } from '@/lib/environment'
import { createLogger } from '@/lib/logs/console/logger'
import { cn } from '@/lib/utils'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import Footer from '@/app/(landing)/components/footer/footer'
import Nav from '@/app/(landing)/components/nav/nav'
import { soehne } from '@/app/fonts/soehne/soehne'
const logger = createLogger('CareersPage')

View File

@@ -7,7 +7,7 @@ import {
LinkedInIcon,
xIcon as XIcon,
} from '@/components/icons'
import { inter } from '@/app/fonts/inter/inter'
import { inter } from '@/app/_styles/fonts/inter/inter'
const blocks = [
'Agent',

View File

@@ -1,11 +1,9 @@
// Hero Components
export { IconButton } from './icon-button'
export { DotPattern } from './landing-canvas/dot-pattern'
export type {
LandingBlockProps,
LandingCardData,
} from './landing-canvas/landing-block/landing-block'
// Landing Block
export { LandingBlock } from './landing-canvas/landing-block/landing-block'
export type { LoopNodeData } from './landing-canvas/landing-block/landing-loop-node'
export { LandingLoopNode } from './landing-canvas/landing-block/landing-loop-node'
@@ -22,9 +20,7 @@ export type {
LandingManualBlock,
LandingViewportApi,
} from './landing-canvas/landing-canvas'
// Landing Canvas
export { CARD_HEIGHT, CARD_WIDTH, LandingCanvas } from './landing-canvas/landing-canvas'
// Landing Edge
export { LandingEdge } from './landing-canvas/landing-edge/landing-edge'
export type { LandingFlowProps } from './landing-canvas/landing-flow'
export { LandingFlow } from './landing-canvas/landing-flow'

View File

@@ -1,6 +1,9 @@
import React from 'react'
import { BookIcon } from 'lucide-react'
import { Tag, type TagProps } from './tag'
import {
Tag,
type TagProps,
} from '@/app/(landing)/components/hero/components/landing-canvas/landing-block/tag'
/**
* Data structure for a landing card component

View File

@@ -1,7 +1,7 @@
'use client'
import React from 'react'
import { LoopBlock } from './loop-block'
import { LoopBlock } from '@/app/(landing)/components/hero/components/landing-canvas/landing-block/loop-block'
/**
* Data structure for the loop node

View File

@@ -2,7 +2,10 @@
import React from 'react'
import { Handle, Position } from 'reactflow'
import { LandingBlock, type LandingCardData } from './landing-block'
import {
LandingBlock,
type LandingCardData,
} from '@/app/(landing)/components/hero/components/landing-canvas/landing-block/landing-block'
/**
* React Flow node component for the landing canvas

View File

@@ -3,9 +3,9 @@
import React from 'react'
import type { Edge, Node } from 'reactflow'
import { ReactFlowProvider } from 'reactflow'
import { DotPattern } from './dot-pattern'
import type { LandingCardData } from './landing-block/landing-block'
import { LandingFlow } from './landing-flow'
import { DotPattern } from '@/app/(landing)/components/hero/components/landing-canvas/dot-pattern'
import type { LandingCardData } from '@/app/(landing)/components/hero/components/landing-canvas/landing-block/landing-block'
import { LandingFlow } from '@/app/(landing)/components/hero/components/landing-canvas/landing-flow'
/**
* Visual constants for landing node dimensions

View File

@@ -3,10 +3,13 @@
import React from 'react'
import ReactFlow, { applyNodeChanges, type NodeChange, useReactFlow } from 'reactflow'
import 'reactflow/dist/style.css'
import { LandingLoopNode } from './landing-block/landing-loop-node'
import { LandingNode } from './landing-block/landing-node'
import { CARD_WIDTH, type LandingCanvasProps } from './landing-canvas'
import { LandingEdge } from './landing-edge/landing-edge'
import { LandingLoopNode } from '@/app/(landing)/components/hero/components/landing-canvas/landing-block/landing-loop-node'
import { LandingNode } from '@/app/(landing)/components/hero/components/landing-canvas/landing-block/landing-node'
import {
CARD_WIDTH,
type LandingCanvasProps,
} from '@/app/(landing)/components/hero/components/landing-canvas/landing-canvas'
import { LandingEdge } from '@/app/(landing)/components/hero/components/landing-canvas/landing-edge/landing-edge'
/**
* Props for the LandingFlow component

View File

@@ -33,7 +33,7 @@ import {
SupabaseIcon,
} from '@/components/icons'
import { LandingPromptStorage } from '@/lib/browser-storage'
import { soehne } from '@/app/fonts/soehne/soehne'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import {
CARD_WIDTH,
IconButton,
@@ -41,7 +41,7 @@ import {
type LandingGroupData,
type LandingManualBlock,
type LandingViewportApi,
} from './components'
} from '@/app/(landing)/components/hero/components'
/**
* Service-specific template messages for the hero input

View File

@@ -1,5 +1,5 @@
import * as Icons from '@/components/icons'
import { inter } from '@/app/fonts/inter/inter'
import { inter } from '@/app/_styles/fonts/inter/inter'
const modelProviderIcons = [
{ icon: Icons.OpenAIIcon, label: 'OpenAI' },

View File

@@ -14,7 +14,7 @@ import {
import { useRouter } from 'next/navigation'
import { createLogger } from '@/lib/logs/console/logger'
import { cn } from '@/lib/utils'
import { inter } from '@/app/fonts/inter/inter'
import { inter } from '@/app/_styles/fonts/inter/inter'
import {
ENTERPRISE_PLAN_FEATURES,
PRO_PLAN_FEATURES,

View File

@@ -1,4 +1,4 @@
import { inter } from '@/app/fonts/inter/inter'
import { inter } from '@/app/_styles/fonts/inter/inter'
interface LandingTemplatePreviewProps {
previewImage: string

View File

@@ -1,7 +1,6 @@
import { inter } from '@/app/fonts/inter/inter'
import LandingTemplatePreview from './components/landing-template-preview'
import { inter } from '@/app/_styles/fonts/inter/inter'
import LandingTemplatePreview from '@/app/(landing)/components/landing-templates/components/landing-template-preview'
// Mock data for templates
const templates = [
{
id: 1,

View File

@@ -1,9 +1,9 @@
'use client'
import { isHosted } from '@/lib/environment'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import Footer from '@/app/(landing)/components/footer/footer'
import Nav from '@/app/(landing)/components/nav/nav'
import { soehne } from '@/app/fonts/soehne/soehne'
interface LegalLayoutProps {
title: string

View File

@@ -9,8 +9,8 @@ import { GithubIcon } from '@/components/icons'
import { useBrandConfig } from '@/lib/branding/branding'
import { isHosted } from '@/lib/environment'
import { createLogger } from '@/lib/logs/console/logger'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import { getFormattedGitHubStars } from '@/app/(landing)/actions/github'
import { soehne } from '@/app/fonts/soehne/soehne'
const logger = createLogger('nav')

View File

@@ -38,7 +38,7 @@ export default function StructuredData() {
url: 'https://sim.ai',
name: 'Sim - AI Agent Workflow Builder',
description:
'Open-source AI agent workflow builder. 50,000+ developers build and deploy agentic workflows. SOC2 and HIPAA compliant.',
'Open-source AI agent workflow builder. 60,000+ developers build and deploy agentic workflows. SOC2 and HIPAA compliant.',
publisher: {
'@id': 'https://sim.ai/#organization',
},
@@ -98,7 +98,7 @@ export default function StructuredData() {
'@id': 'https://sim.ai/#software',
name: 'Sim - AI Agent Workflow Builder',
description:
'Open-source AI agent workflow builder used by 50,000+ developers. Build agentic workflows with visual drag-and-drop interface. SOC2 and HIPAA compliant. Integrate with 100+ apps.',
'Open-source AI agent workflow builder used by 60,000+ developers. Build agentic workflows with visual drag-and-drop interface. SOC2 and HIPAA compliant. Integrate with 100+ apps.',
applicationCategory: 'DeveloperApplication',
applicationSubCategory: 'AI Development Tools',
operatingSystem: 'Web, Windows, macOS, Linux',
@@ -198,7 +198,7 @@ export default function StructuredData() {
name: 'What is Sim?',
acceptedAnswer: {
'@type': 'Answer',
text: 'Sim is an open-source AI agent workflow builder used by 50,000+ developers at trail-blazing startups to Fortune 500 companies. It provides a visual drag-and-drop interface for building and deploying agentic workflows. Sim is SOC2 and HIPAA compliant.',
text: 'Sim is an open-source AI agent workflow builder used by 60,000+ developers at trail-blazing startups to Fortune 500 companies. It provides a visual drag-and-drop interface for building and deploying agentic workflows. Sim is SOC2 and HIPAA compliant.',
},
},
{

View File

@@ -2,7 +2,7 @@
import { useEffect, useState } from 'react'
import Image from 'next/image'
import { inter } from '@/app/fonts/inter/inter'
import { inter } from '@/app/_styles/fonts/inter/inter'
interface Testimonial {
text: string

View File

@@ -5,7 +5,7 @@ import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { FAQ } from '@/lib/blog/faq'
import { getAllPostMeta, getPostBySlug, getRelatedPosts } from '@/lib/blog/registry'
import { buildArticleJsonLd, buildBreadcrumbJsonLd, buildPostMetadata } from '@/lib/blog/seo'
import { soehne } from '@/app/fonts/soehne/soehne'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
export async function generateStaticParams() {
const posts = await getAllPostMeta()

View File

@@ -1,7 +1,7 @@
import Image from 'next/image'
import Link from 'next/link'
import { getAllPostMeta } from '@/lib/blog/registry'
import { soehne } from '@/app/fonts/soehne/soehne'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
export const revalidate = 3600

View File

@@ -2,7 +2,7 @@ import Image from 'next/image'
import Link from 'next/link'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { getAllPostMeta } from '@/lib/blog/registry'
import { soehne } from '@/app/fonts/soehne/soehne'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
export const revalidate = 3600

View File

@@ -3,7 +3,7 @@
import { useEffect } from 'react'
import posthog from 'posthog-js'
import { PostHogProvider as PHProvider } from 'posthog-js/react'
import { getEnv, isTruthy } from '../env'
import { getEnv, isTruthy } from '../../../lib/env'
export function PostHogProvider({ children }: { children: React.ReactNode }) {
useEffect(() => {

View File

@@ -7,7 +7,7 @@ import { z } from 'zod'
import { getSession } from '@/lib/auth'
import { createLogger } from '@/lib/logs/console/logger'
import { generateRequestId } from '@/lib/utils'
import type { CreatorProfileDetails } from '@/types/creator-profile'
import type { CreatorProfileDetails } from '@/app/_types/creator-profile'
const logger = createLogger('CreatorProfilesAPI')

View File

@@ -1,5 +1,5 @@
import { describe, expect, it } from 'vitest'
import { createFileResponse, extractFilename, findLocalFile } from './utils'
import { createFileResponse, extractFilename, findLocalFile } from '@/app/api/files/utils'
describe('extractFilename', () => {
describe('legitimate file paths', () => {

View File

@@ -6,8 +6,6 @@ import { createLogger } from '@/lib/logs/console/logger'
import { estimateTokenCount } from '@/lib/tokenization/estimators'
import { generateRequestId } from '@/lib/utils'
import { getUserId } from '@/app/api/auth/oauth/utils'
import { checkKnowledgeBaseAccess } from '@/app/api/knowledge/utils'
import { calculateCost } from '@/providers/utils'
import {
generateSearchEmbedding,
getDocumentNamesByIds,
@@ -16,7 +14,9 @@ import {
handleTagOnlySearch,
handleVectorOnlySearch,
type SearchResult,
} from './utils'
} from '@/app/api/knowledge/search/utils'
import { checkKnowledgeBaseAccess } from '@/app/api/knowledge/utils'
import { calculateCost } from '@/providers/utils'
const logger = createLogger('VectorSearchAPI')

View File

@@ -42,7 +42,7 @@ import {
handleTagAndVectorSearch,
handleTagOnlySearch,
handleVectorOnlySearch,
} from './utils'
} from '@/app/api/knowledge/search/utils'
describe('Knowledge Search Utils', () => {
beforeEach(() => {

View File

@@ -1,8 +1,8 @@
import { type NextRequest, NextResponse } from 'next/server'
import { getHighestPrioritySubscription } from '@/lib/billing/core/subscription'
import { createLogger } from '@/lib/logs/console/logger'
import { authenticateV1Request } from '@/app/api/v1/auth'
import { RateLimiter } from '@/services/queue/RateLimiter'
import { authenticateV1Request } from './auth'
const logger = createLogger('V1Middleware')
const rateLimiter = new RateLimiter()

View File

@@ -7,7 +7,7 @@ import { getSession } from '@/lib/auth'
import { createLogger } from '@/lib/logs/console/logger'
import { getUserEntityPermissions } from '@/lib/permissions/utils'
import { generateRequestId } from '@/lib/utils'
import { verifyWorkspaceMembership } from './utils'
import { verifyWorkspaceMembership } from '@/app/api/workflows/utils'
const logger = createLogger('WorkflowAPI')

View File

@@ -1,8 +1,8 @@
import { BookOpen, Github, Rss } from 'lucide-react'
import Link from 'next/link'
import { inter } from '@/app/fonts/inter/inter'
import { soehne } from '@/app/fonts/soehne/soehne'
import ChangelogList from './timeline-list'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import ChangelogList from '@/app/changelog/components/timeline-list'
export interface ChangelogEntry {
tag: string

View File

@@ -3,9 +3,9 @@
import React from 'react'
import ReactMarkdown from 'react-markdown'
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
import { inter } from '@/app/fonts/inter/inter'
import { soehne } from '@/app/fonts/soehne/soehne'
import type { ChangelogEntry } from './changelog-content'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import type { ChangelogEntry } from '@/app/changelog/components/changelog-content'
type Props = { initialEntries: ChangelogEntry[] }

View File

@@ -1,5 +1,5 @@
import type { Metadata } from 'next'
import ChangelogContent from './components/changelog-content'
import ChangelogContent from '@/app/changelog/components/changelog-content'
export const metadata: Metadata = {
title: 'Changelog',

View File

@@ -9,9 +9,9 @@ import { Label } from '@/components/ui/label'
import { quickValidateEmail } from '@/lib/email/validation'
import { createLogger } from '@/lib/logs/console/logger'
import { cn } from '@/lib/utils'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import Nav from '@/app/(landing)/components/nav/nav'
import { inter } from '@/app/fonts/inter/inter'
import { soehne } from '@/app/fonts/soehne/soehne'
const logger = createLogger('EmailAuth')

View File

@@ -7,9 +7,9 @@ import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { createLogger } from '@/lib/logs/console/logger'
import { cn } from '@/lib/utils'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import Nav from '@/app/(landing)/components/nav/nav'
import { inter } from '@/app/fonts/inter/inter'
import { soehne } from '@/app/fonts/soehne/soehne'
const logger = createLogger('PasswordAuth')

View File

@@ -8,9 +8,9 @@ import { Label } from '@/components/ui/label'
import { quickValidateEmail } from '@/lib/email/validation'
import { createLogger } from '@/lib/logs/console/logger'
import { cn } from '@/lib/utils'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import Nav from '@/app/(landing)/components/nav/nav'
import { inter } from '@/app/fonts/inter/inter'
import { soehne } from '@/app/fonts/soehne/soehne'
const logger = createLogger('SSOAuth')

View File

@@ -4,9 +4,9 @@ import { useEffect, useState } from 'react'
import { useRouter } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { useBrandConfig } from '@/lib/branding/branding'
import { inter } from '@/app/_styles/fonts/inter/inter'
import { soehne } from '@/app/_styles/fonts/soehne/soehne'
import Nav from '@/app/(landing)/components/nav/nav'
import { inter } from '@/app/fonts/inter/inter'
import { soehne } from '@/app/fonts/soehne/soehne'
interface ChatErrorStateProps {
error: string

View File

@@ -4,7 +4,7 @@ import Image from 'next/image'
import Link from 'next/link'
import { GithubIcon } from '@/components/icons'
import { useBrandConfig } from '@/lib/branding/branding'
import { inter } from '@/app/fonts/inter/inter'
import { inter } from '@/app/_styles/fonts/inter/inter'
interface ChatHeaderProps {
chatConfig: {

View File

@@ -3,7 +3,7 @@
import { memo, useMemo, useState } from 'react'
import { Check, Copy, File as FileIcon, FileText, Image as ImageIcon } from 'lucide-react'
import { Tooltip } from '@/components/emcn'
import MarkdownRenderer from './components/markdown-renderer'
import MarkdownRenderer from '@/app/chat/components/message/components/markdown-renderer'
export interface ChatAttachment {
id: string

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