diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index 728f09f1..00000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,35 +0,0 @@ -/** @type {import("eslint").Linter.Config} */ -const config = { - parser: "@typescript-eslint/parser", - plugins: ["@typescript-eslint", "eslint-plugin-next-on-pages"], - extends: [ - "next/core-web-vitals", - "plugin:@typescript-eslint/recommended-type-checked", - "plugin:@typescript-eslint/stylistic-type-checked", - "plugin:eslint-plugin-next-on-pages/recommended", - ], - rules: { - // These opinionated rules are enabled in stylistic-type-checked above. - // Feel free to reconfigure them to your own preference. - "@typescript-eslint/array-type": "off", - "@typescript-eslint/consistent-type-definitions": "off", - - "@typescript-eslint/consistent-type-imports": [ - "warn", - { - prefer: "type-imports", - fixStyle: "inline-type-imports", - }, - ], - "@typescript-eslint/no-unused-vars": ["warn", { argsIgnorePattern: "^_" }], - "@typescript-eslint/require-await": "off", - "@typescript-eslint/no-misused-promises": [ - "error", - { - checksVoidReturn: { attributes: false }, - }, - ], - }, -}; - -module.exports = config; diff --git a/.gitignore b/.gitignore index f6c4a3eb..d8480f00 100644 --- a/.gitignore +++ b/.gitignore @@ -1,52 +1,43 @@ -.next/ -.turbo -*.sqlite -*.lockb -.next +bun.lockb +.npmrc +.vars +.*.vars .wrangler -drizzle/ -dist/ -pnpm-lock.yaml +.million +# Dependencies node_modules - -# dependencies -/node_modules -/.pnp +.pnp .pnp.js -# testing -/coverage +# Local env files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local -# database -/prisma/db.sqlite -/prisma/db.sqlite-journal +# Testing +coverage -# next.js -/.next/ -/out/ -next-env.d.ts +# Turbo +.turbo -# production -/build +# Vercel +.vercel -# misc -.DS_Store -*.pem +# Build Outputs +.next/ +out/ +build +dist -# debug + +# Debug npm-debug.log* yarn-debug.log* yarn-error.log* -.pnpm-debug.log* -# local env files -# do not commit any .env files to git, except for the .env.example file. https://create.t3.gg/en/usage/env-variables#using-environment-variables -.env -.env*.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo +# Misc +.DS_Store +*.pem diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e8be54ff..00000000 --- a/.gitmodules +++ /dev/null @@ -1,6 +0,0 @@ -[submodule "apps/rowser-rendering"] - path = apps/rowser-rendering - url = https://github.com/dhravya/markdowner -[submodule "apps/browser-rendering"] - path = apps/browser-rendering - url = https://github.com/dhravya/markdowner diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index f3c04e81..00000000 --- a/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -**/.gitignore \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index c50f32c7..00000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2024 Dhravya Shah - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index 0fbe3e85..00000000 --- a/README.md +++ /dev/null @@ -1,90 +0,0 @@ -![og image](https://supermemory.dhr.wtf/og-image.png) - -# SuperMemory - -Interested in helping build the best second brain for everyone? Join the discord https://discord.gg/2X2XsKz5AU. Contributions welcome. - -## 👀 What is this? - -Build your own second brain with supermemory. It's a ChatGPT for your bookmarks. Import tweets or save websites and content using the [chrome extension](https://chromewebstore.google.com/detail/supermemory/afpgkkipfdpeaflnpoaffkcankadgjfc?hl=en-GB&authuser=0) (the extension on webstore is not updated, please use the one in the repo) - -Well, here's the thing - me and @yxshv save a _lot_ of content on the internet. - -Twitter bookmarks, websites, snippets, etc. - -But we never look back to it - to us, it's like throwing information in the void. - -Supermemory fixes this. - -## How do I use this? - -Just go to [supermemory.dhr.wtf](https://supermemory.dhr.wtf) and sign in with your google account. - -To use the chrome extension, - -1. Get the chrome ext (click on the button) -2. Click on the "Extension Auth" button so the extension knows who you are :) - ![chrome](https://i.dhr.wtf/r/Clipboard_Apr_15,_2024_at_10.47 AM.png) - -## 👨‍💻 The Stack - -![overview](https://i.dhr.wtf/r/Clipboard_Apr_14,_2024_at_4.52 PM.png) - -Supermemory has three main modules, managed by [turborepo](https://turbo.build): - -#### `apps/web`: The main web UI. - -The database, auth etc logic is here - -![App preview](https://i.dhr.wtf/r/Clipboard_Apr_14,_2024_at_4.10 PM.png) - -Built with: - -- Nextjs 14 -- [Next Auth](https://next-auth.js.org/) -- [Drizzle ORM](https://drizzle.team/) -- [Cloudflare D1 database](https://developers.cloudflare.com/d1/get-started/) -- Cloudflare ratelimiter -- [TailwindCSS](https://tailwindcss.com) -- [shadcn-ui](https://ui.shadcn.com) -- And some other amazing open source projects like [Novel](https://novel.sh) and [vaul](https://vaul.emilkowal.ski/) -- Hosted on [Cloudflare Pages](https://pages.cloudflare.com/) - -#### `apps/extension`: Chrome extension - -The chrome extension is one of the most important part of the setup, but is not required.This is to easily add pages to your memory. - -![Chrome extension preview](https://i.dhr.wtf/r/Clipboard_Apr_14,_2024_at_3.54 PM.png) - -You can also use it to import all your twitter bookmarks! -![Import bookmarks](https://i.dhr.wtf/r/Clipboard_Apr_14,_2024_at_3.56 PM.png) - -Built with: - -- [CRXJS](https://crxjs.dev/vite-plugin/getting-started/react/create-project) -- Vite -- [TailwindCSS](https://tailwindcss.com) -- [shadcn-ui](https://ui.shadcn.com) -- React - -#### `apps/cf-ai-backend`: This module handles the vector store and AI response generation - -This is where the magic happens! -Built with: - -- Cloudflare Workers -- [Cloudflare AI](https://ai.cloudflare.com) -- [Cloudflare Vectorize](https://developers.cloudflare.com/vectorize/) -- [Cloudflare Queues](https://developers.cloudflare.com/queues/) -- [Cloudflare Browser Rendering](https://developers.cloudflare.com/browser-rendering/) -- [Cloudflare KV](https://developers.cloudflare.com/kv) - -## Contribute or self host - -Supermemory is design to be set up easily locally and super duper easy to set up 💫 - -Please see the [SETUP-GUIDE.md](SETUP-GUIDE.md) for setup instructions. - -### Contributing - -Contributions are very welcome! A contribution can be as small as a ⭐ or even finding and creating issues. diff --git a/SETUP-GUIDE.md b/SETUP-GUIDE.md deleted file mode 100644 index 7d69b545..00000000 --- a/SETUP-GUIDE.md +++ /dev/null @@ -1,79 +0,0 @@ -# Setup guide - -## Prerequisites - -- [bun](https://bun.sh/) -- [turbo](https://turbo.build/repo/docs/installing) -- [wrangler](https://developers.cloudflare.com/workers/cli-wrangler/install-update) - -## Steps - -1. Clone the repo -2. Run `bun install` in the root directory -3. Create a `.dev.vars` file in `apps/web` with the following content: - -```bash -GOOGLE_CLIENT_ID="-" -GOOGLE_CLIENT_SECRET="-" -NEXTAUTH_SECRET='nextauthsecret' -DATABASE_URL='database.sqlite' -NEXTAUTH_URL='http://localhost:3000' -BACKEND_SECURITY_KEY='veryrandomsecuritykey' -``` - -4. Setup the database: - -First, edit the `wrangler.toml` file in `apps/web` to point the d1 database to your account. - -You can create a d1 database by running this command - -``` -wrangler d1 create DATABASE_NAME -``` - -And then replace these values - -``` -[[d1_databases]] -binding = "DATABASE" -database_name = "YOUR_DATABASE_NAME" -database_id = "YOUR_DB_ID" -``` - -Simply run this command in `apps/web` - -``` -wrangler d1 execute dev-d1-anycontext --local --file=db/prepare.sql -``` - -If it runs, you can set up the cloud database as well by removing the `--local` flag. - -5. You need to host your own worker for the `apps/cf-ai-backend` module. - -To do this, first edit the `.dev.vars` file in `apps/cf-ai-backend` with the following content: - -```bash -SECURITY_KEY="veryrandomsecuritykey" -// Why? to generate embeddings with 4000+ tokens -OPENAI_API_KEY="sk-" -``` - -6. Run this command to initialise vector database - > Note: You need to use the workers paid plan to use vectorize for now. - -``` -wrangler vectorize create --dimensions=1536 supermem-vector-1 --metric=cosine -``` - -7. Change the `wrangler.toml` file in `apps/cf-ai-backend` to point to your KV namespace - -8. Run `bun dev` in the root directory and Voila! You have your own supermemory instance running! - -> Note: You need to replace the url `https://cf-ai-backend.dhr.wtf` everywhere with your own url for the cf-ai-backend module. - -## Deploying - -To deploy the web app, run `bun deploy` in the `apps/web` directory. -To deploy the cf-ai-backend module, run `wrangler publish` in the `apps/cf-ai-backend` directory. - -To get the extension running, you need to build it first. Run `bun build` in the `apps/extension` directory and then load the extension in chrome. diff --git a/apps/cf-ai-backend/jest.config.js b/apps/cf-ai-backend/jest.config.js deleted file mode 100644 index 85c5da79..00000000 --- a/apps/cf-ai-backend/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - testEnvironment: "miniflare", - testMatch: ["**/test/**/*.+(ts|tsx)", "**/src/**/(*.)+(spec|test).+(ts|tsx)"], - transform: { - "^.+\\.(ts|tsx)$": "esbuild-jest", - }, -}; diff --git a/apps/cf-ai-backend/tsconfig.json b/apps/cf-ai-backend/tsconfig.json index 9f6f8a73..2b75d5a0 100644 --- a/apps/cf-ai-backend/tsconfig.json +++ b/apps/cf-ai-backend/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { "lib": ["ES2020"], - "types": ["jest", "@cloudflare/workers-types"] + "types": ["@cloudflare/workers-types"] } } diff --git a/apps/cf-ai-backend/wrangler.toml b/apps/cf-ai-backend/wrangler.toml index 83e2d41a..db0ae945 100644 --- a/apps/cf-ai-backend/wrangler.toml +++ b/apps/cf-ai-backend/wrangler.toml @@ -1,5 +1,5 @@ name = "new-cf-ai-backend" -main = "src/server.ts" +main = "src/index.ts" compatibility_date = "2024-02-23" node_compat = true diff --git a/apps/extension/.eslintrc.cjs b/apps/extension/.eslintrc.cjs deleted file mode 100644 index 6e8698b7..00000000 --- a/apps/extension/.eslintrc.cjs +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = { - root: true, - env: { browser: true, es2020: true }, - extends: [ - "eslint:recommended", - "plugin:@typescript-eslint/recommended", - "plugin:react-hooks/recommended", - ], - ignorePatterns: ["dist", ".eslintrc.cjs"], - parser: "@typescript-eslint/parser", - plugins: ["react-refresh"], - rules: { - "react-refresh/only-export-components": [ - "warn", - { allowConstantExport: true }, - ], - }, -}; diff --git a/apps/extension/.gitignore b/apps/extension/.gitignore deleted file mode 100644 index 97d5fffe..00000000 --- a/apps/extension/.gitignore +++ /dev/null @@ -1,26 +0,0 @@ -# Logs -*.zip - -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/apps/extension/README.md b/apps/extension/README.md deleted file mode 100644 index bb156850..00000000 --- a/apps/extension/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# React + TypeScript + Vite - -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. - -Currently, two official plugins are available: - -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh - -## Expanding the ESLint configuration - -If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: - -- Configure the top-level `parserOptions` property like this: - -```js -export default { - // other rules... - parserOptions: { - ecmaVersion: "latest", - sourceType: "module", - project: ["./tsconfig.json", "./tsconfig.node.json"], - tsconfigRootDir: __dirname, - }, -}; -``` - -- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` -- Optionally add `plugin:@typescript-eslint/stylistic-type-checked` -- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list diff --git a/apps/extension/components.json b/apps/extension/components.json deleted file mode 100644 index 6ceb01a1..00000000 --- a/apps/extension/components.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema.json", - "style": "default", - "rsc": false, - "tsx": true, - "tailwind": { - "config": "tailwind.config.js", - "css": "src/global.css", - "baseColor": "stone", - "cssVariables": false, - "prefix": "anycontext-" - }, - "aliases": { - "components": "src/components", - "utils": "src/lib/utils" - } -} diff --git a/apps/extension/icons/icon128.png b/apps/extension/icons/icon128.png deleted file mode 100644 index 9ae12886..00000000 Binary files a/apps/extension/icons/icon128.png and /dev/null differ diff --git a/apps/extension/icons/icon16.png b/apps/extension/icons/icon16.png deleted file mode 100644 index dedf07d2..00000000 Binary files a/apps/extension/icons/icon16.png and /dev/null differ diff --git a/apps/extension/icons/icon32.png b/apps/extension/icons/icon32.png deleted file mode 100644 index 4ceed7ba..00000000 Binary files a/apps/extension/icons/icon32.png and /dev/null differ diff --git a/apps/extension/icons/icon48.png b/apps/extension/icons/icon48.png deleted file mode 100644 index e8beaf4f..00000000 Binary files a/apps/extension/icons/icon48.png and /dev/null differ diff --git a/apps/extension/index.html b/apps/extension/index.html deleted file mode 100644 index e4b78eae..00000000 --- a/apps/extension/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Vite + React + TS - - -
- - - diff --git a/apps/extension/manifest.json b/apps/extension/manifest.json deleted file mode 100644 index 5cf05298..00000000 --- a/apps/extension/manifest.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "manifest_version": 3, - "name": "SuperMemory", - "version": "2.0.0", - "action": { - "default_popup": "index.html" - }, - "icons": { - "16": "icons/icon16.png", - "32": "icons/icon32.png", - "48": "icons/icon48.png", - "128": "icons/icon128.png" - }, - "content_scripts": [ - { - "js": ["src/content.tsx"], - "matches": [ - "http://localhost:3000/*", - "https://opulent-funicular-94rx4v9w775f96q-3000.app.github.dev/*", - "https://anycontext.dhr.wtf/*", - "" - ] - } - ], - "permissions": [ - "activeTab", - "storage", - "http://localhost:3000/*", - "https://opulent-funicular-94rx4v9w775f96q-3000.app.github.dev/*", - "https://anycontext.dhr.wtf/*" - ], - "background": { - "service_worker": "src/background.ts" - } -} diff --git a/apps/extension/package.json b/apps/extension/package.json deleted file mode 100644 index a7f34ea6..00000000 --- a/apps/extension/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "extension", - "private": true, - "version": "0.0.0", - "type": "module", - "scripts": { - "dev": "vite", - "build": "tsc && vite build", - "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", - "preview": "vite preview", - "package": "zip -r extension.zip dist/" - }, - "dependencies": { - "@radix-ui/react-dialog": "^1.0.5", - "@radix-ui/react-dropdown-menu": "^2.0.6", - "@radix-ui/react-popover": "^1.0.7", - "@radix-ui/react-tooltip": "^1.0.7", - "cmdk": "^1.0.0", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "devDependencies": { - "@types/node": "^20.11.22", - "@types/react": "^18.2.56", - "@types/react-dom": "^18.2.19", - "@typescript-eslint/eslint-plugin": "^7.0.2", - "@typescript-eslint/parser": "^7.0.2", - "@vitejs/plugin-react": "^4.2.1", - "eslint": "^8.56.0", - "eslint-plugin-react-hooks": "^4.6.0", - "eslint-plugin-react-refresh": "^0.4.5", - "typescript": "^5.2.2", - "vite": "^5.1.4" - } -} diff --git a/apps/extension/postcss.config.js b/apps/extension/postcss.config.js deleted file mode 100644 index 2aa7205d..00000000 --- a/apps/extension/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -}; diff --git a/apps/extension/public/vite.svg b/apps/extension/public/vite.svg deleted file mode 100644 index e7b8dfb1..00000000 --- a/apps/extension/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/extension/src/App.tsx b/apps/extension/src/App.tsx deleted file mode 100644 index c29d98a2..00000000 --- a/apps/extension/src/App.tsx +++ /dev/null @@ -1,308 +0,0 @@ -import { useEffect, useState } from "react"; -import { z } from "zod"; -import { userObj } from "./types/zods"; -import { getEnv } from "./util"; - -const backendUrl = - getEnv() === "development" - ? "http://localhost:3000" - : "https://supermemory.dhr.wtf"; - -function App() { - const [userData, setUserData] = useState | null>( - null, - ); - - const getUserData = () => { - chrome.runtime.sendMessage({ type: "getJwt" }, (response) => { - const jwt = response.jwt; - const loginButton = document.getElementById("login"); - - if (loginButton) { - if (jwt) { - fetch(`${backendUrl}/api/me`, { - headers: { - Authorization: `Bearer ${jwt}`, - }, - }) - .then((res) => res.json()) - .then((data) => { - const d = userObj.safeParse(data); - if (d.success) { - setUserData(d.data); - } else { - console.error(d.error); - } - }); - loginButton.style.display = "none"; - } - } - }); - }; - - useEffect(() => { - getUserData(); - }, []); - - // TODO: Implement getting bookmarks from Twitter API directly - // const [status, setStatus] = useState(''); - // const [bookmarks, setBookmarks] = useState([]); - - // const fetchBookmarks = (e: React.MouseEvent) => { - // e.preventDefault(); - - // chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) { - // chrome.tabs.sendMessage(tabs[0].id!, { action: 'showProgressIndicator' }); - // }); - - // chrome.tabs.create( - // { url: 'https://twitter.com/i/bookmarks/all' }, - // function (tab) { - // chrome.tabs.onUpdated.addListener(function listener(tabId, info) { - // if (tabId === tab.id && info.status === 'complete') { - // chrome.tabs.onUpdated.removeListener(listener); - - // chrome.runtime.sendMessage( - // { action: 'getAuthData' }, - // function (response) { - // const authorizationHeader = response.authorizationHeader; - // const csrfToken = response.csrfToken; - // const cookies = response.cookies; - - // if (authorizationHeader && csrfToken && cookies) { - // fetchAllBookmarks(authorizationHeader, csrfToken, cookies) - // .then((bookmarks) => { - // console.log('Bookmarks data:', bookmarks); - // setBookmarks(bookmarks); - // chrome.tabs.sendMessage(tabId, { - // action: 'hideProgressIndicator', - // }); - // setStatus( - // `Fetched ${bookmarks.length} bookmarked tweets.`, - // ); - // }) - // .catch((error) => { - // console.error('Error:', error); - // chrome.tabs.sendMessage(tabId, { - // action: 'hideProgressIndicator', - // }); - // setStatus( - // 'Error fetching bookmarks. Please check the console for details.', - // ); - // }); - // } else { - // chrome.tabs.sendMessage(tabId, { - // action: 'hideProgressIndicator', - // }); - // setStatus('Missing authentication data'); - // } - // }, - // ); - // } - // }); - // }, - // ); - // }; - - return ( -
- -
- {userData && ( -
- -
-

{userData.data.user.name}

-

{userData.data.user.email}

-
- {/* TODO: Implement getting bookmarks from API directly */} - {/* -
{status}
- -
- {bookmarks.map((bookmark) => ( -
-

{bookmark.author}

-

{bookmark.date}

-

{bookmark.full_text}

-
- ))} -
*/} -
- )} -
-
- ); -} - -// TODO: Implement getting bookmarks from Twitter API directly -// async function fetchAllBookmarks( -// authorizationHeader: string, -// csrfToken: string, -// cookies: string, -// ): Promise { -// const baseUrl = -// 'https://twitter.com/i/api/graphql/uJEL6XARgGmo2EAsO2Pfkg/Bookmarks'; -// const params = new URLSearchParams({ -// variables: JSON.stringify({ -// count: 100, -// includePromotedContent: true, -// }), -// features: JSON.stringify({ -// graphql_timeline_v2_bookmark_timeline: true, -// rweb_tipjar_consumption_enabled: false, -// responsive_web_graphql_exclude_directive_enabled: true, -// verified_phone_label_enabled: true, -// creator_subscriptions_tweet_preview_api_enabled: true, -// responsive_web_graphql_timeline_navigation_enabled: true, -// responsive_web_graphql_skip_user_profile_image_extensions_enabled: false, -// communities_web_enable_tweet_community_results_fetch: true, -// c9s_tweet_anatomy_moderator_badge_enabled: true, -// tweetypie_unmention_optimization_enabled: true, -// responsive_web_edit_tweet_api_enabled: true, -// graphql_is_translatable_rweb_tweet_is_translatable_enabled: true, -// view_counts_everywhere_api_enabled: true, -// longform_notetweets_consumption_enabled: true, -// responsive_web_twitter_article_tweet_consumption_enabled: true, -// tweet_awards_web_tipping_enabled: false, -// creator_subscriptions_quote_tweet_preview_enabled: false, -// freedom_of_speech_not_reach_fetch_enabled: true, -// standardized_nudges_misinfo: true, -// tweet_with_visibility_results_prefer_gql_limited_actions_policy_enabled: -// true, -// tweet_with_visibility_results_prefer_gql_media_interstitial_enabled: -// false, -// rweb_video_timestamps_enabled: true, -// longform_notetweets_rich_text_read_enabled: true, -// longform_notetweets_inline_media_enabled: true, -// responsive_web_enhance_cards_enabled: false, -// }), -// }); - -// const requestUrl = `${baseUrl}?${params}`; - -// const headers = { -// Authorization: authorizationHeader, -// 'X-Csrf-Token': csrfToken, -// Cookie: cookies, -// }; - -// const bookmarks: TweetData[] = []; -// let nextCursor = null; -// let requestCount = 0; -// const maxRequestsPerWindow = 450; -// const windowDuration = 15 * 60 * 1000; // 15 minutes in milliseconds -// let windowStartTime = Date.now(); - -// do { -// if (nextCursor) { -// params.set( -// 'variables', -// JSON.stringify({ -// count: 100, -// cursor: nextCursor, -// includePromotedContent: true, -// }), -// ); -// } - -// // Check if the rate limit is exceeded -// if (requestCount >= maxRequestsPerWindow) { -// const elapsedTime = Date.now() - windowStartTime; -// if (elapsedTime < windowDuration) { -// const waitTime = windowDuration - elapsedTime; -// await new Promise((resolve) => setTimeout(resolve, waitTime)); -// } -// requestCount = 0; -// windowStartTime = Date.now(); -// } - -// try { -// const response = await fetch(requestUrl, { -// method: 'GET', -// headers: headers, -// }); - -// requestCount++; - -// if (!response.ok) { -// throw new Error(`HTTP error! status: ${response.status}`); -// } - -// const data = await response.json(); -// const timeline = data.data.bookmark_timeline_v2.timeline; - -// timeline.instructions.forEach( -// (instruction: { -// type: string; -// entries: { -// content: { -// entryType: string; -// itemContent: { -// tweet_results: { -// result: { -// legacy: { -// full_text: string; -// created_at: string; -// }; -// core: { -// user_results: { -// result: { -// legacy: { -// screen_name: string; -// }; -// }; -// }; -// }; -// rest_id: string; -// }; -// }; -// }; -// }; -// }[]; -// }) => { -// if (instruction.type === 'TimelineAddEntries') { -// instruction.entries.forEach((entry) => { -// if (entry.content.entryType === 'TimelineTimelineItem') { -// const tweet = entry.content.itemContent.tweet_results.result; -// const tweetData = { -// full_text: tweet.legacy.full_text, -// url: `https://twitter.com/${tweet.core.user_results.result.legacy.screen_name}/status/${tweet.rest_id}`, -// author: tweet.core.user_results.result.legacy.screen_name, -// date: tweet.legacy.created_at, -// tweet_id: tweet.rest_id, -// }; -// bookmarks.push(tweetData); -// } -// }); -// } -// }, -// ); - -// nextCursor = timeline.instructions.find( -// (instruction: { type: string }) => -// instruction.type === 'TimelineTerminateTimeline', -// )?.direction?.cursor; -// } catch (error) { -// console.error('Error fetching bookmarks:', error); -// throw error; -// } -// } while (nextCursor); - -// return bookmarks; -// } -export default App; diff --git a/apps/extension/src/SideBar.tsx b/apps/extension/src/SideBar.tsx deleted file mode 100644 index 385c0f22..00000000 --- a/apps/extension/src/SideBar.tsx +++ /dev/null @@ -1,361 +0,0 @@ -import { useState } from "react"; - -import "./ext.css"; -import { - Tooltip, - TooltipContent, - TooltipProvider, - TooltipTrigger, -} from "./components/ui/tooltip"; -import { FilterSpaces } from "./components/FilterCombobox"; -import { - Dialog, - DialogContent, - DialogHeader, - DialogTitle, - DialogDescription, - DialogTrigger, - DialogFooter, - DialogClose, -} from "./components/ui/dialog"; -import { Space } from "./types/memory"; - -function sendUrlToAPI(spaces: number[]) { - // get the current URL - const url = window.location.href; - - const blacklist = ["localhost:3000", "anycontext.dhr.wtf"]; - // check if the URL is blacklisted - if (blacklist.some((blacklisted) => url.includes(blacklisted))) { - console.log("URL is blacklisted"); - return; - } else { - // const content = Entire page content, but cleaned up for the LLM. No ads, no scripts, no styles, just the text. if article, just the importnat info abou tit. - const content = document.documentElement.innerText; - chrome.runtime.sendMessage({ type: "urlChange", content, url, spaces }); - } -} - -function SideBar({ jwt }: { jwt: string }) { - // TODO: Implement getting bookmarks from Twitter API directly - // chrome.runtime.onMessage.addListener(function (request) { - // if (request.action === 'showProgressIndicator') { - // // TODO: SHOW PROGRESS INDICATOR - // // showProgressIndicator(); - // } else if (request.action === 'hideProgressIndicator') { - // // hideProgressIndicator(); - // } - // }); - - const [savedWebsites, setSavedWebsites] = useState([]); - - const [isSendingData, setIsSendingData] = useState(false); - - const [loading, setLoading] = useState(false); - const [spaces, setSpaces] = useState(); - const [selectedSpaces, setSelectedSpaces] = useState([]); - - const [isImportingTweets, setIsImportingTweets] = useState(false); - - const [log, setLog] = useState([]); - - interface TweetData { - tweetText: string; - postUrl: string; - authorName: string; - handle: string; - time: string; - saveToUser: string; - } - - function sendBookmarkedTweetsToAPI(tweets: TweetData[], token: string) { - chrome.runtime.sendMessage({ - type: "sendBookmarkedTweets", - jwt: token, - tweets, - }); - } - - const fetchSpaces = async () => { - setLoading(true); - chrome.runtime.sendMessage({ type: "fetchSpaces" }, (resp) => { - console.log("response", resp); - setSpaces(resp); - setLoading(false); - }); - }; - - const fetchBookmarks = () => { - const tweets: TweetData[] = []; // Initialize an empty array to hold all tweet elements - - setIsImportingTweets(true); - console.log("Importing tweets"); - - const scrollInterval = 1000; - const scrollStep = 5000; // Pixels to scroll on each step - - let previousTweetCount = 0; - let unchangedCount = 0; - - const scrollToEndIntervalID = setInterval(() => { - window.scrollBy(0, scrollStep); - const currentTweetCount = tweets.length; - if (currentTweetCount === previousTweetCount) { - unchangedCount++; - if (unchangedCount >= 2) { - setLog([ - ...log, - "Scraping complete", - `Total tweets scraped: ${tweets.length}`, - "Downloading tweets as JSON...", - ]); - clearInterval(scrollToEndIntervalID); // Stop scrolling - observer.disconnect(); // Stop observing DOM changes - downloadTweetsAsJson(tweets); // Download the tweets list as a JSON file - } - } else { - unchangedCount = 0; // Reset counter if new tweets were added - } - previousTweetCount = currentTweetCount; // Update previous count for the next check - }, scrollInterval); - - function updateTweets() { - document - .querySelectorAll('article[data-testid="tweet"]') - .forEach((tweetElement) => { - const authorName = ( - tweetElement.querySelector( - '[data-testid="User-Name"]', - ) as HTMLElement - )?.innerText; - - const handle = ( - tweetElement.querySelector('[role="link"]') as HTMLLinkElement - ).href - .split("/") - .pop(); - - const tweetText = ( - tweetElement.querySelector( - '[data-testid="tweetText"]', - ) as HTMLElement - )?.innerText; - const time = ( - tweetElement.querySelector("time") as HTMLTimeElement - ).getAttribute("datetime"); - const postUrl = ( - tweetElement.querySelector( - ".css-175oi2r.r-18u37iz.r-1q142lx a", - ) as HTMLLinkElement - )?.href; - - const isTweetNew = !tweets.some((tweet) => tweet.postUrl === postUrl); - if (isTweetNew) { - tweets.push({ - authorName, - handle: handle ?? "", - tweetText, - time: time ?? "", - postUrl, - saveToUser: jwt, - }); - - setLog([...log, `Scraped tweet: ${tweets.length}`]); - } - }); - } - - // Initially populate the tweets array - updateTweets(); - - // Create a MutationObserver to observe changes in the DOM - const observer = new MutationObserver((mutations) => { - mutations.forEach((mutation) => { - if (mutation.addedNodes.length) { - updateTweets(); // Call updateTweets whenever new nodes are added to the DOM - } - }); - }); - - // Start observing the document body for child list changes - observer.observe(document.body, { childList: true, subtree: true }); - - function downloadTweetsAsJson(tweetsArray: TweetData[]) { - setLog([...log, "Saving the tweets to our database..."]); - sendBookmarkedTweetsToAPI(tweetsArray, jwt); - setIsImportingTweets(false); - } - }; - - return ( - <> - {isImportingTweets && ( -
-
-
- - - -

Importing your tweets...

-
- {log.map((message, index) => ( -

{message}

- ))} -
-
-
-
- )} - - -
- {window.location.href.includes("twitter.com") || - window.location.href.includes("x.com") ? ( - - - - - -

- Import twitter bookmarks -

-
-
- ) : ( - <> - )} - open === true && fetchSpaces()}> - - - - - - - -

- {savedWebsites.includes(window.location.href) - ? "Added to memory" - : "Add to memory"} -

-
-
- - - Add to Memory - - Add the current page to memory - - - - - - { - sendUrlToAPI(selectedSpaces); - setIsSendingData(true); - setTimeout(() => { - setIsSendingData(false); - setSavedWebsites([ - ...savedWebsites, - window.location.href, - ]); - }, 1000); - }} - > - Add - - Cancel - - -
-
-
- - ); -} - -export default SideBar; diff --git a/apps/extension/src/assets/Memories.tsx b/apps/extension/src/assets/Memories.tsx deleted file mode 100644 index 0c138b1e..00000000 --- a/apps/extension/src/assets/Memories.tsx +++ /dev/null @@ -1,69 +0,0 @@ -export const MemoryIcon: React.FC> = ( - props, -) => ( - - - - - -); - -export const SpaceIcon: React.FC> = (props) => ( - - - - -); diff --git a/apps/extension/src/assets/react.svg b/apps/extension/src/assets/react.svg deleted file mode 100644 index 6c87de9b..00000000 --- a/apps/extension/src/assets/react.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/apps/extension/src/background.ts b/apps/extension/src/background.ts deleted file mode 100644 index d2f8759e..00000000 --- a/apps/extension/src/background.ts +++ /dev/null @@ -1,161 +0,0 @@ -import { getEnv } from "./util"; -import { Space } from "./types/memory"; - -const backendUrl = - getEnv() === "development" - ? "http://localhost:3000" - : "https://supermemory.dhr.wtf"; - -interface TweetData { - tweetText: string; - postUrl: string; - authorName: string; - handle: string; - time: string; - saveToUser: string; -} - -// TODO: Implement getting bookmarks from Twitter API directly -// let authorizationHeader: string | null = null; -// let csrfToken: string | null = null; -// let cookies: string | null = null; - -// chrome.webRequest.onBeforeSendHeaders.addListener( -// (details) => { -// for (let i = 0; i < details.requestHeaders!.length; ++i) { -// const header = details.requestHeaders![i]; -// if (header.name.toLowerCase() === 'authorization') { -// authorizationHeader = header.value || null; -// } else if (header.name.toLowerCase() === 'x-csrf-token') { -// csrfToken = header.value || null; -// } else if (header.name.toLowerCase() === 'cookie') { -// cookies = header.value || null; -// } - -// console.log(header, authorizationHeader, csrfToken, cookies) -// } -// }, -// { urls: ['https://twitter.com/*', 'https://x.com/*'] }, -// ['requestHeaders'] -// ); - -chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { - if (request.type === "getJwt") { - chrome.storage.local.get(["jwt"], ({ jwt }) => { - sendResponse({ jwt }); - }); - - return true; - } else if (request.type === "urlChange") { - const content = request.content; - const url = request.url; - const spaces = request.spaces( - // eslint-disable-next-line no-unexpected-multiline - async () => { - chrome.storage.local.get(["jwt"], ({ jwt }) => { - if (!jwt) { - console.error("No JWT found"); - return; - } - fetch(`${backendUrl}/api/store`, { - method: "POST", - headers: { - Authorization: `Bearer ${jwt}`, - }, - body: JSON.stringify({ pageContent: content, url, spaces }), - }).then((ers) => console.log(ers.status)); - }); - }, - )(); - } else if (request.type === "fetchSpaces") { - chrome.storage.local.get(["jwt"], async ({ jwt }) => { - if (!jwt) { - console.error("No JWT found"); - return; - } - const resp = await fetch(`${backendUrl}/api/spaces`, { - headers: { - Authorization: `Bearer ${jwt}`, - }, - }); - - const data: { - message: "OK" | string; - data: Space[] | undefined; - } = await resp.json(); - - if (data.message === "OK" && data.data) { - sendResponse(data.data); - } - }); - - return true; - } else if (request.type === "queryApi") { - const input = request.input; - const jwt = request.jwt; - - (async () => { - await fetch(`${backendUrl}/api/ask`, { - method: "POST", - headers: { - Authorization: `Bearer ${jwt}`, - }, - body: JSON.stringify({ - query: input, - }), - }).then(async (response) => { - if (!response.body) { - throw new Error("No response body"); - } - if (!sender.tab?.id) { - throw new Error("No tab ID"); - } - const reader = response.body.getReader(); - // eslint-disable-next-line no-constant-condition - while (true) { - const { done, value } = await reader.read(); - if (done) break; - // For simplicity, we're sending chunks as they come. - // This might need to be adapted based on your data and needs. - const chunkAsString = new TextDecoder("utf-8") - .decode(value) - .replace("data: ", ""); - chrome.tabs.sendMessage(sender.tab.id, { - action: "streamData", - data: chunkAsString, - }); - } - // Notify the content script that the stream is complete. - chrome.tabs.sendMessage(sender.tab.id, { action: "streamEnd" }); - }); - // Indicate that sendResponse will be called asynchronously. - return true; - })(); - } - // TODO: Implement getting bookmarks from Twitter API directly - // else if (request.action === 'getAuthData') { - // sendResponse({ - // authorizationHeader: authorizationHeader, - // csrfToken: csrfToken, - // cookies: cookies - // }); - // } - else if (request.type === "sendBookmarkedTweets") { - const jwt = request.jwt; - const tweets = request.tweets as TweetData[]; - - (async () => { - await fetch(`${backendUrl}/api/vectorizeTweets`, { - method: "POST", - headers: { - Authorization: `Bearer ${jwt}`, - }, - body: JSON.stringify(tweets), - }).then(async (response) => { - return response.json(); - }); - })(); - - return true; - } -}); diff --git a/apps/extension/src/components/FilterCombobox.tsx b/apps/extension/src/components/FilterCombobox.tsx deleted file mode 100644 index 3c8779b6..00000000 --- a/apps/extension/src/components/FilterCombobox.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import * as React from "react"; -import { PlusCircleIcon, X } from "lucide-react"; -import { Space } from "../types/memory"; -import { - DropdownMenu, - DropdownMenuContent, - DropdownMenuItem, -} from "./ui/dropdown-menu"; -import { DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu"; - -export interface Props extends React.ButtonHTMLAttributes { - selectedSpaces: number[]; - setSelectedSpaces: ( - spaces: number[] | ((prev: number[]) => number[]), - ) => void; - name: string; - spaces: Space[]; - loading: boolean; -} - -export function FilterSpaces({ - loading, - selectedSpaces, - setSelectedSpaces, - spaces, -}: Props) { - console.log(selectedSpaces, spaces); - - const filteredSpaces = spaces.filter((space) => - selectedSpaces.includes(space.id), - ); - const leftSpaces = spaces.filter( - (space) => !selectedSpaces.includes(space.id), - ); - - if (loading) { - return "Loading..."; - } - - return ( -
- {filteredSpaces.length < 1 && "Add to a space"} - {filteredSpaces.map((space) => ( - - setSelectedSpaces((prev) => prev.filter((s) => s !== space.id)) - } - /> - ))} - {leftSpaces.length > 0 && ( - - - - - - {leftSpaces.map((space) => ( - <> - {loading && "Loading..."} - - setSelectedSpaces((prev) => [...prev, space.id]) - } - > - {space.name} - - - ))} - - - )} -
- ); -} - -function SpaceItem({ name, onRemove }: Space & { onRemove: () => void }) { - return ( -
- - {name} -
- ); -} diff --git a/apps/extension/src/components/ui/button.tsx b/apps/extension/src/components/ui/button.tsx deleted file mode 100644 index 6ca7d07a..00000000 --- a/apps/extension/src/components/ui/button.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import * as React from "react"; -import { Slot } from "@radix-ui/react-slot"; -import { cva, type VariantProps } from "class-variance-authority"; - -import { cn } from "../../lib/utils"; - -const buttonVariants = cva( - "anycontext-inline-flex anycontext-items-center anycontext-justify-center anycontext-whitespace-nowrap anycontext-rounded-md anycontext-text-sm anycontext-font-medium anycontext-ring-offset-white anycontext-transition-colors focus-visible:anycontext-outline-none focus-visible:anycontext-ring-2 focus-visible:anycontext-ring-stone-950 focus-visible:anycontext-ring-offset-2 disabled:anycontext-pointer-events-none disabled:anycontext-opacity-50 dark:anycontext-ring-offset-stone-950 dark:focus-visible:anycontext-ring-stone-300", - { - variants: { - variant: { - default: - "anycontext-bg-stone-900 anycontext-text-stone-50 hover:anycontext-bg-stone-900/90 dark:anycontext-bg-stone-50 dark:anycontext-text-stone-900 dark:hover:anycontext-bg-stone-50/90", - destructive: - "anycontext-bg-red-500 anycontext-text-stone-50 hover:anycontext-bg-red-500/90 dark:anycontext-bg-red-900 dark:anycontext-text-stone-50 dark:hover:anycontext-bg-red-900/90", - outline: - "anycontext-border anycontext-border-stone-200 anycontext-bg-white hover:anycontext-bg-stone-100 hover:anycontext-text-stone-900 dark:anycontext-border-stone-800 dark:anycontext-bg-stone-950 dark:hover:anycontext-bg-stone-800 dark:hover:anycontext-text-stone-50", - secondary: - "anycontext-bg-stone-100 anycontext-text-stone-900 hover:anycontext-bg-stone-100/80 dark:anycontext-bg-stone-800 dark:anycontext-text-stone-50 dark:hover:anycontext-bg-stone-800/80", - ghost: - "hover:anycontext-bg-stone-100 hover:anycontext-text-stone-900 dark:hover:anycontext-bg-stone-800 dark:hover:anycontext-text-stone-50", - link: "anycontext-text-stone-900 anycontext-underline-offset-4 hover:anycontext-underline dark:anycontext-text-stone-50", - }, - size: { - default: "anycontext-h-10 anycontext-px-4 anycontext-py-2", - sm: "anycontext-h-9 anycontext-rounded-md anycontext-px-3", - lg: "anycontext-h-11 anycontext-rounded-md anycontext-px-8", - icon: "anycontext-h-10 anycontext-w-10", - }, - }, - defaultVariants: { - variant: "default", - size: "default", - }, - }, -); - -export interface ButtonProps - extends React.ButtonHTMLAttributes, - VariantProps { - asChild?: boolean; -} - -const Button = React.forwardRef( - ({ className, variant, size, asChild = false, ...props }, ref) => { - const Comp = asChild ? Slot : "button"; - return ( - - ); - }, -); -Button.displayName = "Button"; - -export { Button }; diff --git a/apps/extension/src/components/ui/command.tsx b/apps/extension/src/components/ui/command.tsx deleted file mode 100644 index 858b67f4..00000000 --- a/apps/extension/src/components/ui/command.tsx +++ /dev/null @@ -1,162 +0,0 @@ -import * as React from "react"; -import { type DialogProps } from "@radix-ui/react-dialog"; -import { Command as CommandPrimitive } from "cmdk"; -import { Search } from "lucide-react"; - -import { cn } from "../../lib/utils"; -import { Dialog, DialogContent } from "../../components/ui/dialog"; - -const Command = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -Command.displayName = CommandPrimitive.displayName; - -interface CommandDialogProps extends DialogProps {} - -const CommandDialog = ({ children, ...props }: CommandDialogProps) => { - return ( - - - - {children} - - - - ); -}; - -const CommandInput = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( -
- - -
-)); - -CommandInput.displayName = CommandPrimitive.Input.displayName; - -const CommandList = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); - -CommandList.displayName = CommandPrimitive.List.displayName; - -const CommandEmpty = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->((props, ref) => ( - -)); - -CommandEmpty.displayName = CommandPrimitive.Empty.displayName; - -const CommandGroup = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); - -CommandGroup.displayName = CommandPrimitive.Group.displayName; - -const CommandSeparator = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -CommandSeparator.displayName = CommandPrimitive.Separator.displayName; - -const CommandItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); - -CommandItem.displayName = CommandPrimitive.Item.displayName; - -const CommandShortcut = ({ - className, - ...props -}: React.HTMLAttributes) => { - return ( - - ); -}; -CommandShortcut.displayName = "CommandShortcut"; - -export { - Command, - CommandDialog, - CommandInput, - CommandList, - CommandEmpty, - CommandGroup, - CommandItem, - CommandShortcut, - CommandSeparator, -}; diff --git a/apps/extension/src/components/ui/dialog.tsx b/apps/extension/src/components/ui/dialog.tsx deleted file mode 100644 index 583c335d..00000000 --- a/apps/extension/src/components/ui/dialog.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import * as React from "react"; -import * as DialogPrimitive from "@radix-ui/react-dialog"; -import { X } from "lucide-react"; - -import { cn } from "../../lib/utils"; - -const Dialog = DialogPrimitive.Root; - -const DialogTrigger = DialogPrimitive.Trigger; - -const DialogPortal = DialogPrimitive.Portal; - -const DialogClose = DialogPrimitive.Close; - -const DialogOverlay = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -DialogOverlay.displayName = DialogPrimitive.Overlay.displayName; - -const DialogContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - - - - {children} - - - Close - - - -)); -DialogContent.displayName = DialogPrimitive.Content.displayName; - -const DialogHeader = ({ - className, - ...props -}: React.HTMLAttributes) => ( -
-); -DialogHeader.displayName = "DialogHeader"; - -const DialogFooter = ({ - className, - ...props -}: React.HTMLAttributes) => ( -
-); -DialogFooter.displayName = "DialogFooter"; - -const DialogTitle = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -DialogTitle.displayName = DialogPrimitive.Title.displayName; - -const DialogDescription = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -DialogDescription.displayName = DialogPrimitive.Description.displayName; - -export { - Dialog, - DialogPortal, - DialogOverlay, - DialogClose, - DialogTrigger, - DialogContent, - DialogHeader, - DialogFooter, - DialogTitle, - DialogDescription, -}; diff --git a/apps/extension/src/components/ui/dropdown-menu.tsx b/apps/extension/src/components/ui/dropdown-menu.tsx deleted file mode 100644 index fcc1edb2..00000000 --- a/apps/extension/src/components/ui/dropdown-menu.tsx +++ /dev/null @@ -1,204 +0,0 @@ -import * as React from "react"; -import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu"; -import { Check, ChevronRight, Circle } from "lucide-react"; - -import { cn } from "../../lib/utils"; - -const DropdownMenu = DropdownMenuPrimitive.Root; - -const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger; - -const DropdownMenuGroup = DropdownMenuPrimitive.Group; - -const DropdownMenuPortal = DropdownMenuPrimitive.Portal; - -const DropdownMenuSub = DropdownMenuPrimitive.Sub; - -const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup; - -const DropdownMenuSubTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean; - } ->(({ className, inset, children, ...props }, ref) => ( - - {children} - - -)); -DropdownMenuSubTrigger.displayName = - DropdownMenuPrimitive.SubTrigger.displayName; - -const DropdownMenuSubContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -DropdownMenuSubContent.displayName = - DropdownMenuPrimitive.SubContent.displayName; - -const DropdownMenuContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, sideOffset = 4, ...props }, ref) => ( - - - -)); -DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName; - -const DropdownMenuItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean; - } ->(({ className, inset, ...props }, ref) => ( - -)); -DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName; - -const DropdownMenuCheckboxItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, checked, ...props }, ref) => ( - - - - - - - {children} - -)); -DropdownMenuCheckboxItem.displayName = - DropdownMenuPrimitive.CheckboxItem.displayName; - -const DropdownMenuRadioItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, children, ...props }, ref) => ( - - - - - - - {children} - -)); -DropdownMenuRadioItem.displayName = DropdownMenuPrimitive.RadioItem.displayName; - -const DropdownMenuLabel = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef & { - inset?: boolean; - } ->(({ className, inset, ...props }, ref) => ( - -)); -DropdownMenuLabel.displayName = DropdownMenuPrimitive.Label.displayName; - -const DropdownMenuSeparator = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, ...props }, ref) => ( - -)); -DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName; - -const DropdownMenuShortcut = ({ - className, - ...props -}: React.HTMLAttributes) => { - return ( - - ); -}; -DropdownMenuShortcut.displayName = "DropdownMenuShortcut"; - -export { - DropdownMenu, - DropdownMenuTrigger, - DropdownMenuContent, - DropdownMenuItem, - DropdownMenuCheckboxItem, - DropdownMenuRadioItem, - DropdownMenuLabel, - DropdownMenuSeparator, - DropdownMenuShortcut, - DropdownMenuGroup, - DropdownMenuPortal, - DropdownMenuSub, - DropdownMenuSubContent, - DropdownMenuSubTrigger, - DropdownMenuRadioGroup, -}; diff --git a/apps/extension/src/components/ui/input.tsx b/apps/extension/src/components/ui/input.tsx deleted file mode 100644 index 4771795a..00000000 --- a/apps/extension/src/components/ui/input.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as React from "react"; - -import { cn } from "../../lib/utils"; - -export interface InputProps - extends React.InputHTMLAttributes {} - -const Input = React.forwardRef( - ({ className, type, ...props }, ref) => { - return ( - - ); - }, -); -Input.displayName = "Input"; - -export { Input }; diff --git a/apps/extension/src/components/ui/popover.tsx b/apps/extension/src/components/ui/popover.tsx deleted file mode 100644 index e1b9282d..00000000 --- a/apps/extension/src/components/ui/popover.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import * as React from "react"; -import * as PopoverPrimitive from "@radix-ui/react-popover"; - -import { cn } from "../../lib/utils"; - -const Popover = PopoverPrimitive.Root; - -const PopoverTrigger = PopoverPrimitive.Trigger; - -const PopoverContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( - - - -)); -PopoverContent.displayName = PopoverPrimitive.Content.displayName; - -export { Popover, PopoverTrigger, PopoverContent }; diff --git a/apps/extension/src/components/ui/tooltip.tsx b/apps/extension/src/components/ui/tooltip.tsx deleted file mode 100644 index 12185db5..00000000 --- a/apps/extension/src/components/ui/tooltip.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as React from "react"; -import * as TooltipPrimitive from "@radix-ui/react-tooltip"; - -import { cn } from "../../lib/utils"; - -const TooltipProvider = TooltipPrimitive.Provider; - -const Tooltip = TooltipPrimitive.Root; - -const TooltipTrigger = TooltipPrimitive.Trigger; - -const TooltipContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, sideOffset = 4, ...props }, ref) => ( - -)); -TooltipContent.displayName = TooltipPrimitive.Content.displayName; - -export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }; diff --git a/apps/extension/src/content.tsx b/apps/extension/src/content.tsx deleted file mode 100644 index 83d976cd..00000000 --- a/apps/extension/src/content.tsx +++ /dev/null @@ -1,45 +0,0 @@ -window.addEventListener("message", (event) => { - if (event.source !== window) { - return; - } - const { jwt } = event.data; - - if (jwt) { - if ( - !( - window.location.hostname === "localhost" || - window.location.hostname === "anycontext.dhr.wtf" || - window.location.hostname === "supermemory.dhr.wtf" - ) - ) { - console.log( - "JWT is only allowed to be used on localhost or anycontext.dhr.wtf", - ); - return; - } - - chrome.storage.local.set({ jwt }, () => {}); - } -}); - -const appContainer = document.createElement("div"); -appContainer.id = "anycontext-app-container"; - -// First in the body, above the content -document.body.insertBefore(appContainer, document.body.firstChild); - -appContainer.style.zIndex = "9999"; - -import ReactDOM from "react-dom/client"; -import SideBar from "./SideBar"; - -// get JWT from local storage -const jwt = chrome.storage.local.get("jwt").then((data) => { - return data.jwt; -}) as Promise; - -jwt.then((token) => { - ReactDOM.createRoot( - document.getElementById("anycontext-app-container")!, - ).render(); -}); diff --git a/apps/extension/src/ext.css b/apps/extension/src/ext.css deleted file mode 100644 index bf7a4156..00000000 --- a/apps/extension/src/ext.css +++ /dev/null @@ -1,85 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -.anycontext-combobox-button { - padding: 0.5rem 1rem; - display: flex; - flex-direction: row; - justify-items: center; - align-items: center; - gap: 0.5rem; - @apply anycontext-rounded-md dark:anycontext-bg-white/5 anycontext-bg-black/5; -} - -.anycontext-overlay { - position: fixed; - top: 0; - left: 0; - min-height: 100vh; - width: 100%; - height: 100%; - background-color: rgba(0, 0, 0, 0.5); - z-index: 99998; -} - -.anycontext-sidebar { - position: fixed; - top: 0; - right: 0; - min-height: 100vh; - width: 100%; - max-width: 31%; /* Responsive width */ - z-index: 99999; - padding: 8px 16px; /* px-4 py-2 */ -} - -.anycontext-sidebar-content { - position: relative; - display: flex; - flex-direction: column; - height: 95vh; - background-color: white; - border-radius: 8px; /* rounded-lg */ - padding: 8px; /* px-2 */ - box-shadow: - 0 4px 6px -1px rgba(0, 0, 0, 0.1), - 0 2px 4px -1px rgba(0, 0, 0, 0.06); /* shadow-md */ -} - -.anycontext-close-button { - position: absolute; - right: 0; - padding: 8px; /* p-2 */ - border-radius: 4px; /* rounded-md */ - margin: 8px; /* m-2 */ -} - -.anycontext-close-button:hover { - background-color: rgba(114, 87, 255, 0.5); /* hover:bg-[#7257ff]/50 */ - color: white; /* hover:text-white */ -} - -.anycontext-open-button { - color: white; - background-color: #7257ff50; /* bg-indigo-600 */ - background-opacity: 75%; - cursor: pointer; - padding: 8px; /* px-4 py-2 */ - border-radius: 4px 0 0 4px; /* rounded-l-md */ - display: flex; - align-items: center; - justify-content: space-between; -} - -.anycontext-header { - margin: 16px; /* m-4 */ - font-weight: 600; /* font-semibold */ - font-size: 1.25rem; /* text-xl */ - color: black; -} - -.anycontext-icon { - height: 24px; /* h-6 */ - width: 24px; /* w-6 */ -} diff --git a/apps/extension/src/lib/utils.ts b/apps/extension/src/lib/utils.ts deleted file mode 100644 index 365058ce..00000000 --- a/apps/extension/src/lib/utils.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { type ClassValue, clsx } from "clsx"; -import { twMerge } from "tailwind-merge"; - -export function cn(...inputs: ClassValue[]) { - return twMerge(clsx(inputs)); -} diff --git a/apps/extension/src/main.tsx b/apps/extension/src/main.tsx deleted file mode 100644 index b5c00920..00000000 --- a/apps/extension/src/main.tsx +++ /dev/null @@ -1,9 +0,0 @@ -import React from "react"; -import ReactDOM from "react-dom/client"; -import App from "./App.tsx"; - -ReactDOM.createRoot(document.getElementById("root")!).render( - - - , -); diff --git a/apps/extension/src/types/memory.ts b/apps/extension/src/types/memory.ts deleted file mode 100644 index 03ffb848..00000000 --- a/apps/extension/src/types/memory.ts +++ /dev/null @@ -1,4 +0,0 @@ -export type Space = { - id: number; - name: string; -}; diff --git a/apps/extension/src/types/zods.ts b/apps/extension/src/types/zods.ts deleted file mode 100644 index 3316aa16..00000000 --- a/apps/extension/src/types/zods.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { z } from "zod"; - -export const userObj = z.object({ - message: z.string(), - data: z.object({ - session: z.object({ - sessionToken: z.string(), - userId: z.string(), - expires: z.string(), - }), - user: z.object({ - id: z.string(), - name: z.string(), - email: z.string().nullable().optional(), - emailVerified: z.string().nullable(), - image: z.string().nullable().optional(), - }), - }), -}); diff --git a/apps/extension/src/util.ts b/apps/extension/src/util.ts deleted file mode 100644 index d2ea35d3..00000000 --- a/apps/extension/src/util.ts +++ /dev/null @@ -1,13 +0,0 @@ -export const getEnv = () => { - // chrome.management.getSelf((self) => { - // if (self.installType === 'development') { - // return "development" - // } - // else { - // return "production" - // } - // }) - - // return null - return "production"; -}; diff --git a/apps/extension/src/vite-env.d.ts b/apps/extension/src/vite-env.d.ts deleted file mode 100644 index 11f02fe2..00000000 --- a/apps/extension/src/vite-env.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// diff --git a/apps/extension/tailwind.config.js b/apps/extension/tailwind.config.js deleted file mode 100644 index ed971842..00000000 --- a/apps/extension/tailwind.config.js +++ /dev/null @@ -1,42 +0,0 @@ -import tailwindcssAnimate from "tailwindcss-animate"; -/** @type {import('tailwindcss').Config} */ -export default { - //darkMode: "prefe", - content: [ - "./pages/**/*.{ts,tsx}", - "./components/**/*.{ts,tsx}", - "./app/**/*.{ts,tsx}", - "./src/**/*.{ts,tsx}", - "index.html", - ], - prefix: "anycontext-", - theme: { - container: { - center: true, - padding: "2rem", - screens: { - "2xl": "1400px", - }, - }, - extend: { - keyframes: { - "accordion-down": { - from: { height: "0" }, - to: { height: "var(--radix-accordion-content-height)" }, - }, - "accordion-up": { - from: { height: "var(--radix-accordion-content-height)" }, - to: { height: "0" }, - }, - }, - animation: { - "accordion-down": "accordion-down 0.2s ease-out", - "accordion-up": "accordion-up 0.2s ease-out", - }, - }, - }, - plugins: [tailwindcssAnimate], - corePlugins: { - preflight: false, - }, -}; diff --git a/apps/extension/tsconfig.json b/apps/extension/tsconfig.json deleted file mode 100644 index 2fefaeb1..00000000 --- a/apps/extension/tsconfig.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "compilerOptions": { - "target": "ES2020", - "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], - "module": "ESNext", - "skipLibCheck": true, - - /* Bundler mode */ - "moduleResolution": "bundler", - "allowImportingTsExtensions": true, - "resolveJsonModule": true, - "isolatedModules": true, - "noEmit": true, - "jsx": "react-jsx", - - /* Linting */ - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true - }, - "include": ["src"], - "references": [{ "path": "./tsconfig.node.json" }], - "types": ["chrome"] -} diff --git a/apps/extension/tsconfig.node.json b/apps/extension/tsconfig.node.json deleted file mode 100644 index 97ede7ee..00000000 --- a/apps/extension/tsconfig.node.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "compilerOptions": { - "composite": true, - "skipLibCheck": true, - "module": "ESNext", - "moduleResolution": "bundler", - "allowSyntheticDefaultImports": true, - "strict": true - }, - "include": ["vite.config.ts"] -} diff --git a/apps/extension/vite.config.ts b/apps/extension/vite.config.ts deleted file mode 100644 index c2b53f80..00000000 --- a/apps/extension/vite.config.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Plugin, defineConfig } from "vite"; -import react from "@vitejs/plugin-react"; -import { crx } from "@crxjs/vite-plugin"; -import manifest from "./manifest.json"; -import path from "path"; - -// eslint-disable-next-line @typescript-eslint/no-explicit-any -const viteManifestHackIssue846: Plugin & { - renderCrxManifest: (manifest: unknown, bundle: any) => void; -} = { - // Workaround from https://github.com/crxjs/chrome-extension-tools/issues/846#issuecomment-1861880919. - name: "manifestHackIssue846", - renderCrxManifest(_manifest, bundle) { - bundle["manifest.json"] = bundle[".vite/manifest.json"]; - bundle["manifest.json"].fileName = "manifest.json"; - delete bundle[".vite/manifest.json"]; - }, -}; - -export default defineConfig({ - plugins: [react(), crx({ manifest }), viteManifestHackIssue846], - resolve: { - alias: { - "@": path.resolve(__dirname, "./src"), - }, - }, -}); diff --git a/apps/web-v2/.eslintrc.json b/apps/web-v2/.eslintrc.json deleted file mode 100644 index abd7bea7..00000000 --- a/apps/web-v2/.eslintrc.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": [ - "next/core-web-vitals", - "plugin:eslint-plugin-next-on-pages/recommended" - ], - "plugins": ["eslint-plugin-next-on-pages"] -} diff --git a/apps/web-v2/.gitignore b/apps/web-v2/.gitignore deleted file mode 100644 index c213988d..00000000 --- a/apps/web-v2/.gitignore +++ /dev/null @@ -1,40 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js -.yarn/install-state.gz - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# production -/build - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# local env files -.env*.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo -next-env.d.ts - -# wrangler files -.wrangler -.dev.vars diff --git a/apps/web-v2/README.md b/apps/web-v2/README.md deleted file mode 100644 index 64c8f3bc..00000000 --- a/apps/web-v2/README.md +++ /dev/null @@ -1,70 +0,0 @@ -This is a [Next.js](https://nextjs.org/) project bootstrapped with [`c3`](https://developers.cloudflare.com/pages/get-started/c3). - -## Getting Started - -First, run the development server: - -```bash -npm run dev -# or -yarn dev -# or -pnpm dev -# or -bun dev -``` - -Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. - -## Cloudflare integration - -Besides the `dev` script mentioned above `c3` has added a few extra scripts that allow you to integrate the application with the [Cloudflare Pages](https://pages.cloudflare.com/) environment, these are: - -- `pages:build` to build the application for Pages using the [`@cloudflare/next-on-pages`](https://github.com/cloudflare/next-on-pages) CLI -- `preview` to locally preview your Pages application using the [Wrangler](https://developers.cloudflare.com/workers/wrangler/) CLI -- `deploy` to deploy your Pages application using the [Wrangler](https://developers.cloudflare.com/workers/wrangler/) CLI - -> **Note:** while the `dev` script is optimal for local development you should preview your Pages application as well (periodically or before deployments) in order to make sure that it can properly work in the Pages environment (for more details see the [`@cloudflare/next-on-pages` recommended workflow](https://github.com/cloudflare/next-on-pages/blob/05b6256/internal-packages/next-dev/README.md#recommended-workflow)) - -### Bindings - -Cloudflare [Bindings](https://developers.cloudflare.com/pages/functions/bindings/) are what allows you to interact with resources available in the Cloudflare Platform. - -You can use bindings during development, when previewing locally your application and of course in the deployed application: - -- To use bindings in dev mode you need to define them in the `next.config.js` file under `setupDevBindings`, this mode uses the `next-dev` `@cloudflare/next-on-pages` submodule. For more details see its [documentation](https://github.com/cloudflare/next-on-pages/blob/05b6256/internal-packages/next-dev/README.md). - -- To use bindings in the preview mode you need to add them to the `pages:preview` script accordingly to the `wrangler pages dev` command. For more details see its [documentation](https://developers.cloudflare.com/workers/wrangler/commands/#dev-1) or the [Pages Bindings documentation](https://developers.cloudflare.com/pages/functions/bindings/). - -- To use bindings in the deployed application you will need to configure them in the Cloudflare [dashboard](https://dash.cloudflare.com/). For more details see the [Pages Bindings documentation](https://developers.cloudflare.com/pages/functions/bindings/). - -#### KV Example - -`c3` has added for you an example showing how you can use a KV binding. - -In order to enable the example: - -- Search for javascript/typescript lines containing the following comment: - ```ts - // KV Example: - ``` - and uncomment the commented lines below it. -- Do the same in the `wrangler.toml` file, where - the comment is: - ``` - # KV Example: - ``` -- If you're using TypeScript run the `cf-typegen` script to update the `env.d.ts` file: - ```bash - npm run cf-typegen - # or - yarn cf-typegen - # or - pnpm cf-typegen - # or - bun cf-typegen - ``` - -After doing this you can run the `dev` or `preview` script and visit the `/api/hello` route to see the example in action. - -Finally, if you also want to see the example work in the deployed application make sure to add a `MY_KV_NAMESPACE` binding to your Pages application in its [dashboard kv bindings settings section](https://dash.cloudflare.com/?to=/:account/pages/view/:pages-project/settings/functions#kv_namespace_bindings_section). After having configured it make sure to re-deploy your application. diff --git a/apps/web-v2/components.json b/apps/web-v2/components.json deleted file mode 100644 index 268ae38d..00000000 --- a/apps/web-v2/components.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "https://ui.shadcn.com/schema.json", - "style": "default", - "rsc": true, - "tsx": true, - "tailwind": { - "config": "tailwind.config.ts", - "css": "src/app/globals.css", - "baseColor": "zinc", - "cssVariables": true, - "prefix": "" - }, - "aliases": { - "components": "@/components", - "utils": "@/lib/utils" - } -} diff --git a/apps/web-v2/env.d.ts b/apps/web-v2/env.d.ts deleted file mode 100644 index ac17de2c..00000000 --- a/apps/web-v2/env.d.ts +++ /dev/null @@ -1,47 +0,0 @@ -// Generated by Wrangler -// by running `wrangler types --env-interface CloudflareEnv env.d.ts` - -interface CloudflareEnv { - RATELIMITER: RateLimitBinding; -} - -export interface RateLimitBinding { - limit: LimitFunc; -} - -export interface LimitFunc { - (options: LimitOptions): Promise; -} - -interface RateLimitResult { - success: boolean; -} - -export interface LimitOptions { - key: string; -} - -export interface RateLimitResponse { - key: string; - success: boolean; -} - -export interface RateLimitOptions { - continueOnRateLimit: boolean; -} - -export type RateLimitKeyFunc = { - (c: Context): string; -}; - -declare global { - namespace NodeJS { - interface ProcessEnv { - // [key: string]: string | undefined; - RATELIMITER: RateLimitBinding; - CLOUDFLARE_TURNSTILE_TOKEN: string; - } - } -} - -export {}; diff --git a/apps/web-v2/next.config.mjs b/apps/web-v2/next.config.mjs deleted file mode 100644 index b0c1476c..00000000 --- a/apps/web-v2/next.config.mjs +++ /dev/null @@ -1,13 +0,0 @@ -import { setupDevPlatform } from "@cloudflare/next-on-pages/next-dev"; - -// Here we use the @cloudflare/next-on-pages next-dev module to allow us to use bindings during local development -// (when running the application with `next dev`), for more information see: -// https://github.com/cloudflare/next-on-pages/blob/5712c57ea7/internal-packages/next-dev/README.md -if (process.env.NODE_ENV === "development") { - await setupDevPlatform(); -} - -/** @type {import('next').NextConfig} */ -const nextConfig = {}; - -export default nextConfig; diff --git a/apps/web-v2/package.json b/apps/web-v2/package.json deleted file mode 100644 index 69a39888..00000000 --- a/apps/web-v2/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "web-v2", - "version": "0.1.0", - "private": true, - "scripts": { - "dev": "next dev", - "build": "next build", - "start": "next start", - "lint": "next lint", - "pages:build": "bunx @cloudflare/next-on-pages", - "preview": "bun pages:build && wrangler pages dev", - "deploy": "bun pages:build && wrangler pages deploy", - "cf-typegen": "wrangler types --env-interface CloudflareEnv env.d.ts" - }, - "dependencies": { - "@radix-ui/react-toast": "^1.1.5", - "class-variance-authority": "^0.7.0", - "clsx": "^2.1.1", - "lucide-react": "^0.378.0", - "next": "14.1.0", - "react": "^18", - "react-dom": "^18", - "tailwind-merge": "^2.3.0", - "tailwindcss-animate": "^1.0.7" - }, - "devDependencies": { - "@cloudflare/next-on-pages": "1", - "@cloudflare/workers-types": "^4.20240512.0", - "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18", - "autoprefixer": "^10.0.1", - "eslint": "^8", - "eslint-config-next": "14.1.0", - "eslint-plugin-next-on-pages": "^1.11.3", - "postcss": "^8", - "tailwindcss": "^3.3.0", - "typescript": "^5", - "vercel": "^34.2.0", - "wrangler": "^3.57.0" - } -} diff --git a/apps/web-v2/postcss.config.js b/apps/web-v2/postcss.config.js deleted file mode 100644 index 12a703d9..00000000 --- a/apps/web-v2/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -}; diff --git a/apps/web-v2/public/favicon.ico b/apps/web-v2/public/favicon.ico deleted file mode 100644 index dd86c6dd..00000000 Binary files a/apps/web-v2/public/favicon.ico and /dev/null differ diff --git a/apps/web-v2/public/og-image.png b/apps/web-v2/public/og-image.png deleted file mode 100644 index c5a61b17..00000000 Binary files a/apps/web-v2/public/og-image.png and /dev/null differ diff --git a/apps/web-v2/public/site.webmanifest b/apps/web-v2/public/site.webmanifest deleted file mode 100644 index c903e516..00000000 --- a/apps/web-v2/public/site.webmanifest +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "Supermemory - your second brain.", - "short_name": "Supermemory", - "icons": [ - { - "src": "/icons/android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "/icons/android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "theme_color": "#ffffff", - "background_color": "#ffffff", - "display": "standalone" -} diff --git a/apps/web-v2/src/app/(landing)/page.tsx b/apps/web-v2/src/app/(landing)/page.tsx deleted file mode 100644 index 5351c51b..00000000 --- a/apps/web-v2/src/app/(landing)/page.tsx +++ /dev/null @@ -1,102 +0,0 @@ -import RotatingIcons from "./RotatingIcons"; -import Hero from "./Hero"; -import Navbar from "./Navbar"; -import Cta from "./Cta"; -import { Toaster } from "@/components/ui/toaster"; -import Features from "./Features"; -import Footer from "./footer"; -import { Metadata } from "next"; - -export const runtime = "edge"; - -export const metadata: Metadata = { - title: "Supermemory - Your personal second brain.", - description: - "Bring saved information from all over the internet into one place where you can connect it, and ask AI about it", - openGraph: { - images: [ - { - url: "https://supermemory.ai/og-image.png", - width: 1200, - height: 627, - alt: "Supermemory - Your personal second brain.", - }, - ], - }, - metadataBase: { - host: "https://supermemory.ai", - href: "/", - origin: "https://supermemory.ai", - password: "supermemory", - hash: "supermemory", - pathname: "/", - search: "", - username: "supermemoryai", - hostname: "supermemory.ai", - port: "", - protocol: "https:", - searchParams: new URLSearchParams(""), - toString: () => "https://supermemory.ai/", - toJSON: () => "https://supermemory.ai/", - }, - twitter: { - card: "summary_large_image", - site: "https://supermemory.ai", - creator: "https://supermemory.ai", - title: "Supermemory - Your personal second brain.", - description: - "Bring saved information from all over the internet into one place where you can connect it, and ask AI about it", - images: [ - { - url: "https://supermemory.ai/og-image.png", - width: 1200, - height: 627, - alt: "Supermemory - Your personal second brain.", - }, - ], - }, -}; - -export default function Home() { - return ( -
- - - {/* Background gradients */} -
-
-
-
- - {/* a blue gradient line that's slightly tilted with blur (a lotof blur)*/} -
-
-
- -
-
-
-
- - {/* Hero section */} - - - {/* Features section */} - - - - - - - - -
-
- ); -} diff --git a/apps/web-v2/src/app/globals.css b/apps/web-v2/src/app/globals.css deleted file mode 100644 index 67115e30..00000000 --- a/apps/web-v2/src/app/globals.css +++ /dev/null @@ -1,132 +0,0 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - -@layer base { - :root { - --foreground-rgb: 255, 255, 255; - --background-start-rgb: 0, 0, 0; - --background-end-rgb: 0, 0, 0; - --black-bg: #0f1114; - --soft-foreground: #ffffff; - --soft-foreground-text: #b2bcca; - - --background: 216, 14%, 7%; - --foreground: 240 10% 3.9%; - - --card: 0 0% 100%; - --card-foreground: 240 10% 3.9%; - - --popover: 0 0% 100%; - --popover-foreground: 240 10% 3.9%; - - --primary: 240 5.9% 10%; - --primary-foreground: 0 0% 98%; - - --secondary: 240 4.8% 95.9%; - --secondary-foreground: 240 5.9% 10%; - - --muted: 240 4.8% 95.9%; - --muted-foreground: 240 3.8% 46.1%; - - --accent: 240 4.8% 95.9%; - --accent-foreground: 240 5.9% 10%; - - --destructive: 0 84.2% 60.2%; - --destructive-foreground: 0 0% 98%; - - --border: 240 5.9% 90%; - --input: 240 5.9% 90%; - --ring: 240 10% 3.9%; - - --radius: 0.5rem; - } - - .dark { - --background: 216, 14%, 7%; - --foreground: 0 0% 98%; - - --card: 240 10% 3.9%; - --card-foreground: 0 0% 98%; - - --popover: 240 10% 3.9%; - --popover-foreground: 0 0% 98%; - - --primary: 0 0% 98%; - --primary-foreground: 240 5.9% 10%; - - --secondary: 240 3.7% 15.9%; - --secondary-foreground: 0 0% 98%; - - --muted: 240 3.7% 15.9%; - --muted-foreground: 240 5% 64.9%; - - --accent: 240 3.7% 15.9%; - --accent-foreground: 0 0% 98%; - - --destructive: 0 62.8% 30.6%; - --destructive-foreground: 0 0% 98%; - - --border: 240 3.7% 15.9%; - --input: 240 3.7% 15.9%; - --ring: 240 4.9% 83.9%; - } -} - -@layer base { - * { - @apply border-border; - } - body { - @apply bg-background text-foreground; - } -} - -html { - scroll-behavior: smooth; -} - -/* width */ -::-webkit-scrollbar { - width: 8px; -} - -/* Track */ -::-webkit-scrollbar-track { - background: transparent; -} - -/* Handle */ -::-webkit-scrollbar-thumb { - background: #131f2c; -} - -/* Handle on hover */ -::-webkit-scrollbar-thumb:hover { - background: #22303d; -} - -body { - color: rgb(var(--foreground-rgb)); - background: linear-gradient(to bottom, transparent, var(--black-bg)) - var(--black-bg); -} - -@layer utilities { - .text-balance { - text-wrap: balance; - } -} - -@keyframes rotate { - 0% { - transform: rotate(0deg) translateX(130px); /* Adjust radius */ - } - 100% { - transform: rotate(360deg) translateX(130px); /* Adjust radius */ - } -} - -.icon-container { - animation: rotate 10s linear infinite; -} diff --git a/apps/web-v2/src/app/layout.tsx b/apps/web-v2/src/app/layout.tsx deleted file mode 100644 index 4af34eee..00000000 --- a/apps/web-v2/src/app/layout.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import type { Metadata } from "next"; -import { Inter } from "next/font/google"; -import "./globals.css"; -import Script from "next/script"; - -const inter = Inter({ subsets: ["latin"] }); - -export const metadata: Metadata = { - title: "Supermemory - Your personal second brain.", - description: - "Bring saved information from all over the internet into one place where you can connect it, and ask AI about it", -}; - -export default function RootLayout({ - children, -}: Readonly<{ - children: React.ReactNode; -}>) { - return ( - - - - -
- {children} -
- - - ); -} diff --git a/apps/web/src/app/not-found.tsx b/apps/web/src/app/not-found.tsx deleted file mode 100644 index 3409889a..00000000 --- a/apps/web/src/app/not-found.tsx +++ /dev/null @@ -1,58 +0,0 @@ -export const runtime = "edge"; - -export default function NotFound() { - return ( - <> - 404: This page could not be found. -
-
-