From fddc21aab2f9f59623d76802d0ab2b17cbe7fa5b Mon Sep 17 00:00:00 2001 From: Mahesh Sanikommmu Date: Sat, 16 Aug 2025 20:15:39 -0700 Subject: added usage notes --- CONTRIBUTE.md | 288 +++++++++ README.md | 114 ++-- .../components/views/connections-tab-content.tsx | 664 ++++++++++----------- apps/web/public/add-connections.png | Bin 0 -> 339198 bytes apps/web/public/add-memory.png | Bin 0 -> 371710 bytes apps/web/public/chat.png | Bin 0 -> 342407 bytes apps/web/public/mcp.png | Bin 0 -> 421670 bytes 7 files changed, 645 insertions(+), 421 deletions(-) create mode 100644 CONTRIBUTE.md create mode 100644 apps/web/public/add-connections.png create mode 100644 apps/web/public/add-memory.png create mode 100644 apps/web/public/chat.png create mode 100644 apps/web/public/mcp.png diff --git a/CONTRIBUTE.md b/CONTRIBUTE.md new file mode 100644 index 00000000..b3ea376f --- /dev/null +++ b/CONTRIBUTE.md @@ -0,0 +1,288 @@ +# Contributing to supermemory + +Thank you for your interest in contributing to supermemory! We welcome contributions from developers of all skill levels. This guide will help you get started with contributing to our AI-powered memory layer API. + +## πŸš€ Quick Start + +### Prerequisites + +Before you begin, ensure you have the following installed: + +- **Bun** (>= 1.2.17) - Our preferred package manager +- **Git** for version control + +### Setting Up the Development Environment + +1. **Fork and Clone the Repository** + + ```bash + git clone https://github.com/your-username/supermemory-app.git + cd supermemory-app + ``` + +2. **Install Dependencies** + + ```bash + bun install + ``` + +3. **Set Up Environment Variables** + + ```bash + # Copy the example environment file + cp .env.example .env.local + + # Edit the file with your configuration + # You'll need to add your API keys and database URLs + ``` + +4. **Start the Development Server** + + ```bash + bun run dev + ``` + + This will start all applications in the monorepo. The web app will be available at `http://localhost:3000`. + +## πŸ“ Project Structure + +supermemory is organized as a monorepo using Turbo: + +``` +supermemory-app/ +β”œβ”€β”€ apps/ +β”‚ └── web/ # Next.js web application +β”œβ”€β”€ packages/ +β”‚ β”œβ”€β”€ ui/ # Shared UI components +β”‚ β”œβ”€β”€ lib/ # Shared utilities and logic +β”‚ β”œβ”€β”€ hooks/ # Shared React hooks +β”‚ β”œβ”€β”€ validation/ # Zod schemas and validation +β”‚ β”œβ”€β”€ eslint-config/ # ESLint configurations +β”‚ └── typescript-config/ # TypeScript configurations +└── turbo.json # Turbo configuration +``` + +## πŸ› οΈ Development Workflow + +### Available Scripts + +- `bun run dev` - Start development servers for all apps +- `bun run build` - Build all applications +- `bun run format-lint` - Format and lint code using Biome +- `bun run check-types` - Type check all packages + +### Code Quality + +We use several tools to maintain code quality: + +- **Biome** for linting and formatting +- **TypeScript** for type safety +- **Turbo** for build optimization + +Before submitting a PR, ensure your code passes all checks: + +```bash +bun run format-lint +bun run check-types +bun run build +``` + +### Tech Stack + +- **Frontend**: Next.js 15, React 19, TypeScript +- **Styling**: Tailwind CSS, Radix UI components +- **State Management**: Zustand, TanStack Query +- **Build Tool**: Turbo (monorepo) +- **Package Manager**: Bun +- **Deployment**: Cloudflare (OpenNext.js) + +## 🎯 How to Contribute + +### Types of Contributions + +We welcome various types of contributions: + +- πŸ› **Bug fixes** +- ✨ **New features** +- 🎨 **UI/UX enhancements** +- ⚑ **Performance optimizations** + +### Finding Issues to Work On + +1. Check our [Issues](https://github.com/supermemoryai/supermemory/issues) page +2. Look for issues labeled `good first issue` for beginners +3. Issues labeled `help wanted` are great for contributors +4. Feel free to propose new features by opening an issue first + +### Making Changes + +1. **Create a Branch** + + ```bash + git checkout -b feature/your-feature-name + # or + git checkout -b fix/your-bug-fix + ``` + +2. **Make Your Changes** + - Follow our coding standards (see below) + - Write clear, concise commit messages + - Add tests if applicable + - Update documentation if needed + +3. **Test Your Changes** + ```bash + bun run dev # Test locally + bun run build # Ensure it builds + bun run format-lint # Check formatting + bun run check-types # Check types + ``` + +## πŸ“ Coding Standards + +### General Guidelines + +- Use **TypeScript** for all new code +- Follow the existing code style and patterns +- Write self-documenting code with clear variable names +- Add JSDoc comments for complex functions +- Keep functions small and focused + +### Component Guidelines + +- Use functional components with hooks +- Prefer composition over inheritance +- Extract reusable logic into custom hooks +- Use proper TypeScript types for props + +### File Naming + +- Use `kebab-case` for file names +- Use `PascalCase` for component files +- Use `camelCase` for utility functions + +### Import Organization + +```typescript +// 1. React and Next.js imports +import React from 'react'; +import { NextPage } from 'next'; + +// 2. Third-party libraries +import { clsx } from 'clsx'; +import { motion } from 'motion'; + +// 3. Internal packages +import { Button } from '@repo/ui'; +import { useAuth } from '@repo/lib'; + +// 4. Relative imports +import { Header } from './header'; +import { Footer } from './footer'; +``` + +## πŸ”„ Pull Request Process + +### Before Submitting + +1. Ensure your branch is up to date with `main` +2. Run all quality checks +3. Test your changes thoroughly +4. Update documentation if needed + +### PR Guidelines + +1. **Title**: Use a clear, descriptive title + - βœ… `feat: add semantic search to memory graph` + - βœ… `fix: resolve authentication redirect loop` + - ❌ `update stuff` + +2. **Description**: Include: + - What changes you made and why + - Screenshots for UI changes + - Any breaking changes + - Related issue numbers + +3. **Size**: Keep PRs focused and reasonably sized + - Prefer multiple small PRs over one large PR + - Each PR should address a single concern + +### Review Process + +1. All PRs require at least one review +2. Address feedback promptly and professionally +3. Be open to suggestions and improvements +4. Maintain a collaborative attitude + +## πŸ› Reporting Issues + +### Bug Reports + +When reporting bugs, please include: + +- **Environment**: OS, Node.js version, browser +- **Steps to reproduce** the issue +- **Expected behavior** +- **Actual behavior** +- **Screenshots** if applicable +- **Error messages** or console logs + +### Feature Requests + +For feature requests, please provide: + +- **Problem statement**: What problem does this solve? +- **Proposed solution**: How should it work? +- **Alternatives considered**: Other approaches you've thought of +- **Additional context**: Any relevant information + +## πŸ—οΈ Architecture Guidelines + +### State Management + +- Use **Zustand** for global state +- Use **TanStack Query** for server state +- Keep state as local as possible +- Use proper TypeScript types for state + +### API Integration + +- Use the existing API client patterns +- Handle loading and error states properly +- Implement proper error boundaries +- Use optimistic updates where appropriate + +### Performance + +- Use React.memo() for expensive components +- Implement proper loading states +- Optimize images and assets +- Use code splitting where beneficial + +## 🀝 Community Guidelines + +### Code of Conduct + +- Be respectful and inclusive +- Welcome newcomers and help them learn +- Focus on constructive feedback +- Maintain professionalism in all interactions + +### Getting Help + +- **Discord**: Join our community server +- **GitHub Discussions**: For questions and ideas +- **Issues**: For bug reports and feature requests +- **Email**: [dhravya@supermemory.com](mailto:dhravya@supermemory.com) + +## πŸ“„ License + +By contributing to supermemory, you agree that your contributions will be licensed under the same license as the project. + +## πŸ™ Recognition + +All contributors will be recognized in our README and release notes. We appreciate every contribution, no matter how small! + +--- + +Thank you for contributing to supermemory! Together, we're building the future of AI-powered knowledge management. πŸš€ diff --git a/README.md b/README.md index afd2af2a..28179e96 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -
+
supermemory Logo
@@ -6,94 +6,70 @@ supermemory
-## ✨ Features +## Features ### Core Functionality -- **Add Memories from Any Content**: Easily add memories from URLs, PDFs, and plain textβ€”just paste, upload, or link. -- **Chat with Your Memories**: Converse with your stored content using natural language chat. -- **Supermemory MCP Integration**: Seamlessly connect with all major AI tools (Claude, Cursor, etc.) via Supermemory MCP. -- **Graph View for All Memories**: Visualize and explore your memories and their connections in an interactive graph mode. - -## πŸ—οΈ Architecture -This is a **Turborepo monorepo** +- **[Add Memories from Any Content](#add-memory)**: Easily add memories from URLs, PDFs, and plain textβ€”just paste, upload, or link. +- **[Chat with Your Memories](#chat-memories)**: Converse with your stored content using natural language chat. +- **[Supermemory MCP Integration](#mcp-integration)**: Seamlessly connect with all major AI tools (Claude, Cursor, etc.) via Supermemory MCP. -### Technology Stack -- **Frontend**: Next.js 15 with React 19 -- **Backend**: Hono API framework on Cloudflare Workers -- **Database**: PostgreSQL with Drizzle ORM -- **Authentication**: Better Auth with organization support -- **Package Manager**: Bun -- **Monorepo**: Turbo for build optimization -- **Styling**: Tailwind CSS with Radix UI components -- **Monitoring**: Sentry for error tracking and performance monitoring +## How do i use this? -### Project Structure -``` -β”œβ”€β”€ apps/ -β”‚ └── web/ # Next.js web application -β”œβ”€β”€ packages/ # Shared packages and utilities -β”œβ”€β”€ CLAUDE.md # Development guidelines for AI assistants -β”œβ”€β”€ turbo.json # Turborepo configuration -└── package.json # Root package configuration -``` +Go to [app.supermemory.ai](https://app.supermemory.ai) and sign into with your account -## πŸš€ Getting Started +1. Start Adding Memory with your choose of format (Note, Link, File) +
+ supermemory +
-### Prerequisites -- **Bun** package manager +2. You can also Connect to your favourite services (Notion, Google Drive, OneDrive) +
+ supermemory +
-### Installation +3. Once Memories are added, you can chat with Supermemory by clicking on "Open Chat" and retrieve info from your saved memories +
+ supermemory +
-1. **Clone the repository** - ```bash - git clone https://github.com/supermemoryai/supermemory-app.git - cd supermemory - ``` +4. Add MCP to your AI Tools (by clicking on "Connect to your AI" and select the AI tool you are trying to integrate) +
+ supermemory +
-2. **Install dependencies** - ```bash - bun install - ``` +## Support -3. **Environment Setup** - - Create environment files for each app: - ```bash - # Copy environment templates - cp apps/web/.env.example apps/web/.env.local - ``` +Have questions or feedback? We're here to help: -### Development +- Email: [dhravya@supermemory.com](mailto:dhravya@supermemory.com) +- Documentation: [docs.supermemory.ai](https://docs.supermemory.ai) -#### Start all applications in development mode: -```bash -bun run dev -``` +## Contributing -This will start: -- Web app at `http://localhost:3000` -- API endpoints available through the web app +We welcome contributions from developers of all skill levels! Whether you're fixing bugs, adding features, or improving documentation, your help makes supermemory better for everyone. +### Quick Start for Contributors -## πŸ§ͺ Development Workflow +1. **Fork and clone** the repository +2. **Install dependencies** with `bun install` +3. **Set up your environment** by copying `.env.example` to `.env.local` +4. **Start developing** with `bun run dev` -### Code Quality -- **Linting & Formatting**: Uses Biome for consistent code style -- **Type Safety**: Strict TypeScript configuration across all packages +For detailed guidelines, development setup, coding standards, and the complete contribution workflow, please see our [**Contributing Guide**](CONTRIBUTE.md). -## 🀝 Contributing +### Ways to Contribute -### Development Guidelines -- Follow the code style enforced by Biome -- Write tests for new features -- Update documentation when adding new functionality -- Ensure all checks pass before submitting PRs +- πŸ› **Bug fixes** - Help us squash those pesky issues +- ✨ **New features** - Add functionality that users will love +- 🎨 **UI/UX improvements** - Make the interface more intuitive +- ⚑ **Performance optimizations** - Help us make supermemory faster +Check out our [Issues](https://github.com/supermemoryai/supermemory/issues) page for `good first issue` and `help wanted` labels to get started! -## πŸ’¬ Support & Community +## Updates & Roadmap -- **Issues**: [GitHub Issues](https://github.com/supermemoryai/supermemory-app/issues) -- **Email**: [dhravya@supermemory.com](mailto:dhravya@supermemory.com) -- **Twitter**: [@supermemoryai](https://x.com/supermemoryai) +Stay up to date with the latest improvements: +- [Changelog](https://docs.supermemory.ai/changelog/overview) +- [X](https://x.com/supermemoryai) diff --git a/apps/web/components/views/connections-tab-content.tsx b/apps/web/components/views/connections-tab-content.tsx index 177c2a4d..a94ed708 100644 --- a/apps/web/components/views/connections-tab-content.tsx +++ b/apps/web/components/views/connections-tab-content.tsx @@ -1,382 +1,342 @@ -"use client" +'use client'; -import { $fetch } from "@lib/api" +import { $fetch } from '@lib/api'; import { - fetchConnectionsFeature, - fetchConsumerProProduct, -} from "@repo/lib/queries" -import { Button } from "@repo/ui/components/button" + fetchConnectionsFeature, + fetchConsumerProProduct, +} from '@repo/lib/queries'; +import { Button } from '@repo/ui/components/button'; import { - Dialog, - DialogContent, - DialogDescription, - DialogHeader, - DialogTitle, -} from "@repo/ui/components/dialog" -import { Skeleton } from "@repo/ui/components/skeleton" -import type { ConnectionResponseSchema } from "@repo/validation/api" -import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query" -import { GoogleDrive, Notion, OneDrive } from "@ui/assets/icons" -import { useCustomer } from "autumn-js/react" -import { Plus, Trash2 } from "lucide-react" -import { AnimatePresence, motion } from "motion/react" -import Link from "next/link" -import { useEffect, useState } from "react" -import { toast } from "sonner" -import type { z } from "zod" -import { useProject } from "@/stores" -import { analytics } from "@/lib/analytics" + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, +} from '@repo/ui/components/dialog'; +import { Skeleton } from '@repo/ui/components/skeleton'; +import type { ConnectionResponseSchema } from '@repo/validation/api'; +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { GoogleDrive, Notion, OneDrive } from '@ui/assets/icons'; +import { useCustomer } from 'autumn-js/react'; +import { Trash2 } from 'lucide-react'; +import { AnimatePresence, motion } from 'motion/react'; +import Link from 'next/link'; +import { useEffect } from 'react'; +import { toast } from 'sonner'; +import type { z } from 'zod'; +import { useProject } from '@/stores'; +import { analytics } from '@/lib/analytics'; // Define types -type Connection = z.infer +type Connection = z.infer; // Connector configurations const CONNECTORS = { - "google-drive": { - title: "Google Drive", - description: "Connect your Google Docs, Sheets, and Slides", - icon: GoogleDrive, - }, - notion: { - title: "Notion", - description: "Import your Notion pages and databases", - icon: Notion, - }, - onedrive: { - title: "OneDrive", - description: "Access your Microsoft Office documents", - icon: OneDrive, - }, -} as const + 'google-drive': { + title: 'Google Drive', + description: 'Connect your Google Docs, Sheets, and Slides', + icon: GoogleDrive, + }, + notion: { + title: 'Notion', + description: 'Import your Notion pages and databases', + icon: Notion, + }, + onedrive: { + title: 'OneDrive', + description: 'Access your Microsoft Office documents', + icon: OneDrive, + }, +} as const; -type ConnectorProvider = keyof typeof CONNECTORS +type ConnectorProvider = keyof typeof CONNECTORS; export function ConnectionsTabContent() { - const queryClient = useQueryClient() - const [showAddDialog, setShowAddDialog] = useState(false) - const { selectedProject } = useProject() - const autumn = useCustomer() + const queryClient = useQueryClient(); + const { selectedProject } = useProject(); + const autumn = useCustomer(); - const handleUpgrade = async () => { - try { - await autumn.attach({ - productId: "consumer_pro", - successUrl: "https://app.supermemory.ai/", - }) - window.location.reload() - } catch (error) { - console.error(error) - } - } + const handleUpgrade = async () => { + try { + await autumn.attach({ + productId: 'consumer_pro', + successUrl: 'https://app.supermemory.ai/', + }); + window.location.reload(); + } catch (error) { + console.error(error); + } + }; - const { data: connectionsCheck } = fetchConnectionsFeature(autumn as any) - const connectionsUsed = connectionsCheck?.balance ?? 0 - const connectionsLimit = connectionsCheck?.included_usage ?? 0 + const { data: connectionsCheck } = fetchConnectionsFeature(autumn as any); + const connectionsUsed = connectionsCheck?.balance ?? 0; + const connectionsLimit = connectionsCheck?.included_usage ?? 0; - const { data: proCheck } = fetchConsumerProProduct(autumn as any) - const isProUser = proCheck?.allowed ?? false + const { data: proCheck } = fetchConsumerProProduct(autumn as any); + const isProUser = proCheck?.allowed ?? false; - const canAddConnection = connectionsUsed < connectionsLimit + const canAddConnection = connectionsUsed < connectionsLimit; - // Fetch connections - const { - data: connections = [], - isLoading, - error, - } = useQuery({ - queryKey: ["connections"], - queryFn: async () => { - const response = await $fetch("@post/connections/list", { - body: { - containerTags: [], - }, - }) + // Fetch connections + const { + data: connections = [], + isLoading, + error, + } = useQuery({ + queryKey: ['connections'], + queryFn: async () => { + const response = await $fetch('@post/connections/list', { + body: { + containerTags: [], + }, + }); - if (response.error) { - throw new Error(response.error?.message || "Failed to load connections") - } + if (response.error) { + throw new Error( + response.error?.message || 'Failed to load connections' + ); + } - return response.data as Connection[] - }, - staleTime: 30 * 1000, - refetchInterval: 60 * 1000, - }) + return response.data as Connection[]; + }, + staleTime: 30 * 1000, + refetchInterval: 60 * 1000, + }); - // Show error toast if connections fail to load - useEffect(() => { - if (error) { - toast.error("Failed to load connections", { - description: error instanceof Error ? error.message : "Unknown error", - }) - } - }, [error]) + // Show error toast if connections fail to load + useEffect(() => { + if (error) { + toast.error('Failed to load connections', { + description: error instanceof Error ? error.message : 'Unknown error', + }); + } + }, [error]); - // Add connection mutation - const addConnectionMutation = useMutation({ - mutationFn: async (provider: ConnectorProvider) => { - // Check if user can add connections - if (!canAddConnection && !isProUser) { - throw new Error( - "Free plan doesn't include connections. Upgrade to Pro for unlimited connections.", - ) - } + // Add connection mutation + const addConnectionMutation = useMutation({ + mutationFn: async (provider: ConnectorProvider) => { + // Check if user can add connections + if (!canAddConnection && !isProUser) { + throw new Error( + "Free plan doesn't include connections. Upgrade to Pro for unlimited connections." + ); + } - const response = await $fetch("@post/connections/:provider", { - params: { provider }, - body: { - redirectUrl: window.location.href, - containerTags: [selectedProject], - }, - }) + const response = await $fetch('@post/connections/:provider', { + params: { provider }, + body: { + redirectUrl: window.location.href, + containerTags: [selectedProject], + }, + }); - // biome-ignore lint/style/noNonNullAssertion: its fine - if ("data" in response && !("error" in response.data!)) { - return response.data - } + // biome-ignore lint/style/noNonNullAssertion: its fine + if ('data' in response && !('error' in response.data!)) { + return response.data; + } - throw new Error(response.error?.message || "Failed to connect") - }, - onSuccess: (data, provider) => { - analytics.connectionAdded(provider) - analytics.connectionAuthStarted() - if (data?.authLink) { - window.location.href = data.authLink - } - }, - onError: (error, provider) => { - analytics.connectionAuthFailed() - toast.error(`Failed to connect ${provider}`, { - description: error instanceof Error ? error.message : "Unknown error", - }) - }, - }) + throw new Error(response.error?.message || 'Failed to connect'); + }, + onSuccess: (data, provider) => { + analytics.connectionAdded(provider); + analytics.connectionAuthStarted(); + if (data?.authLink) { + window.location.href = data.authLink; + } + }, + onError: (error, provider) => { + analytics.connectionAuthFailed(); + toast.error(`Failed to connect ${provider}`, { + description: error instanceof Error ? error.message : 'Unknown error', + }); + }, + }); - // Delete connection mutation - const deleteConnectionMutation = useMutation({ - mutationFn: async (connectionId: string) => { - await $fetch(`@delete/connections/${connectionId}`) - }, - onSuccess: () => { - analytics.connectionDeleted() - toast.success( - "Connection removal has started. supermemory will permanently delete the documents in the next few minutes.", - ) - queryClient.invalidateQueries({ queryKey: ["connections"] }) - }, - onError: (error) => { - toast.error("Failed to remove connection", { - description: error instanceof Error ? error.message : "Unknown error", - }) - }, - }) + // Delete connection mutation + const deleteConnectionMutation = useMutation({ + mutationFn: async (connectionId: string) => { + await $fetch(`@delete/connections/${connectionId}`); + }, + onSuccess: () => { + analytics.connectionDeleted(); + toast.success( + 'Connection removal has started. supermemory will permanently delete the documents in the next few minutes.' + ); + queryClient.invalidateQueries({ queryKey: ['connections'] }); + }, + onError: (error) => { + toast.error('Failed to remove connection', { + description: error instanceof Error ? error.message : 'Unknown error', + }); + }, + }); - const getProviderIcon = (provider: string) => { - const connector = CONNECTORS[provider as ConnectorProvider] - if (connector) { - const Icon = connector.icon - return - } - return πŸ“Ž - } + const getProviderIcon = (provider: string) => { + const connector = CONNECTORS[provider as ConnectorProvider]; + if (connector) { + const Icon = connector.icon; + return ; + } + return πŸ“Ž; + }; - return ( -
-
-
-

- Connect your favorite services to import documents -

- {!isProUser && ( -

- Connections require a Pro subscription -

- )} -
- - - -
+ return ( +
+
+

+ Connect your favorite services to import documents +

+ {!isProUser && ( +

+ Connections require a Pro subscription +

+ )} +
- {/* Show upgrade prompt for free users */} - {!isProUser && ( - -

- πŸ”Œ Connections are a Pro feature -

-

- Connect Google Drive, Notion, OneDrive and more to automatically - sync your documents. -

- -
- )} + {/* Show upgrade prompt for free users */} + {!isProUser && ( + +

+ πŸ”Œ Connections are a Pro feature +

+

+ Connect Google Drive, Notion, OneDrive and more to automatically + sync your documents. +

+ +
+ )} - {isLoading ? ( -
- {[...Array(2)].map((_, i) => ( - - - - ))} -
- ) : connections.length === 0 ? ( - -

No connections yet

- - - -
- ) : ( - - - {connections.map((connection, index) => ( - -
- - {getProviderIcon(connection.provider)} - -
-

- {connection.provider.replace("-", " ")} -

- {connection.email && ( -

- {connection.email} -

- )} -
-
- - - -
- ))} -
-
- )} + {isLoading ? ( +
+ {[...Array(2)].map((_, i) => ( + + + + ))} +
+ ) : connections.length === 0 ? ( + +

No connections yet

+

+ Choose a service below to connect +

+
+ ) : ( + + + {connections.map((connection, index) => ( + +
+ + {getProviderIcon(connection.provider)} + +
+

+ {connection.provider.replace('-', ' ')} +

+ {connection.email && ( +

+ {connection.email} +

+ )} +
+
+ + + +
+ ))} +
+
+ )} - {/* Add Connection Dialog */} - - {showAddDialog && ( - - - - - Add a Connection - - Choose a service to connect and import your documents - - -
- {Object.entries(CONNECTORS).map( - ([provider, config], index) => { - const Icon = config.icon - return ( - - - - ) - }, - )} -
-
-
-
- )} -
-
- ) + {/* Available Connections Section */} +
+

+ Available Connections +

+
+ {Object.entries(CONNECTORS).map(([provider, config], index) => { + const Icon = config.icon; + return ( + + + + ); + })} +
+
+
+ ); } diff --git a/apps/web/public/add-connections.png b/apps/web/public/add-connections.png new file mode 100644 index 00000000..1f49f4da Binary files /dev/null and b/apps/web/public/add-connections.png differ diff --git a/apps/web/public/add-memory.png b/apps/web/public/add-memory.png new file mode 100644 index 00000000..248ea3e3 Binary files /dev/null and b/apps/web/public/add-memory.png differ diff --git a/apps/web/public/chat.png b/apps/web/public/chat.png new file mode 100644 index 00000000..869c27ec Binary files /dev/null and b/apps/web/public/chat.png differ diff --git a/apps/web/public/mcp.png b/apps/web/public/mcp.png new file mode 100644 index 00000000..05ceb619 Binary files /dev/null and b/apps/web/public/mcp.png differ -- cgit v1.2.3