aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorDhravya Shah <[email protected]>2025-10-03 02:37:50 -0700
committerDhravya Shah <[email protected]>2025-10-03 02:37:50 -0700
commitbe34a14550e03302c160310464deef541bda3154 (patch)
tree16104bc3501962a3030937426eb2982a952e7908 /apps
parentfix: docs (diff)
parentfix: raycast org selection based api key creation (#447) (diff)
downloadsupermemory-be34a14550e03302c160310464deef541bda3154.tar.xz
supermemory-be34a14550e03302c160310464deef541bda3154.zip
Merge branch 'main' of https://github.com/supermemoryai/supermemory
Diffstat (limited to 'apps')
-rw-r--r--apps/raycast-extension/.gitignore14
-rw-r--r--apps/raycast-extension/CHANGELOG.md6
-rw-r--r--apps/raycast-extension/README.md35
-rw-r--r--apps/raycast-extension/assets/extension-icon.pngbin0 -> 22106 bytes
-rw-r--r--apps/raycast-extension/eslint.config.js4
-rw-r--r--apps/raycast-extension/metadata/supermemory-1.pngbin0 -> 2741204 bytes
-rw-r--r--apps/raycast-extension/metadata/supermemory-2.pngbin0 -> 2912310 bytes
-rw-r--r--apps/raycast-extension/package-lock.json3233
-rw-r--r--apps/raycast-extension/package.json62
-rw-r--r--apps/raycast-extension/src/add-memory.tsx110
-rw-r--r--apps/raycast-extension/src/api.ts227
-rw-r--r--apps/raycast-extension/src/search-memories.tsx253
-rw-r--r--apps/raycast-extension/tsconfig.json16
-rw-r--r--apps/web/app/(navigation)/page.tsx2
-rw-r--r--apps/web/components/chrome-extension-button.tsx234
-rw-r--r--apps/web/components/content-cards/google-docs.tsx88
-rw-r--r--apps/web/components/content-cards/note.tsx96
-rw-r--r--apps/web/components/content-cards/tweet.tsx66
-rw-r--r--apps/web/components/content-cards/website.tsx88
-rw-r--r--apps/web/components/header.tsx27
-rw-r--r--apps/web/components/masonry-memory-list.tsx8
-rw-r--r--apps/web/components/views/add-memory/action-buttons.tsx118
-rw-r--r--apps/web/components/views/add-memory/index.tsx7
-rw-r--r--apps/web/components/views/billing.tsx10
-rw-r--r--apps/web/components/views/integrations.tsx246
-rw-r--r--apps/web/components/views/profile.tsx51
-rw-r--r--apps/web/public/icons/chrome-transparent.svg13
-rw-r--r--apps/web/public/images/extension-bg.pngbin0 -> 39989 bytes
-rw-r--r--apps/web/public/images/extension-logo.pngbin0 -> 33814 bytes
29 files changed, 4868 insertions, 146 deletions
diff --git a/apps/raycast-extension/.gitignore b/apps/raycast-extension/.gitignore
new file mode 100644
index 00000000..84fc7188
--- /dev/null
+++ b/apps/raycast-extension/.gitignore
@@ -0,0 +1,14 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+
+# Raycast specific files
+raycast-env.d.ts
+.raycast-swift-build
+.swiftpm
+compiled_raycast_swift
+compiled_raycast_rust
+
+# misc
+.DS_Store
diff --git a/apps/raycast-extension/CHANGELOG.md b/apps/raycast-extension/CHANGELOG.md
new file mode 100644
index 00000000..06b6fe0e
--- /dev/null
+++ b/apps/raycast-extension/CHANGELOG.md
@@ -0,0 +1,6 @@
+# supermemory-raycast Changelog
+
+## [Initial Version] - {2025-09-27}
+
+- Added Supermemory integration with Add Memory and Search Memories commands
+- Added project organization support for memories \ No newline at end of file
diff --git a/apps/raycast-extension/README.md b/apps/raycast-extension/README.md
new file mode 100644
index 00000000..76e0667d
--- /dev/null
+++ b/apps/raycast-extension/README.md
@@ -0,0 +1,35 @@
+# Raycast Extension for Supermemory
+
+A Raycast extension that lets you add memories and search through your Supermemory collection directly from Raycast.
+
+## Setup
+
+1. Install the extension in Raycast
+2. Get your API key from [app.supermemory.ai](https://app.supermemory.ai)
+3. Open the extension preferences and enter your API key
+
+## Features
+
+### Add Memory
+- Add new memories to your Supermemory collection
+- Organize memories by project
+- Add optional titles and URLs
+- Keyboard shortcut: Cmd+Enter to submit
+
+### Search Memories
+- Search through your entire Supermemory collection
+- Real-time search with debouncing
+- View detailed memory information
+- Copy content or open related URLs
+- Shows relevance scores and creation dates
+
+## Commands
+
+- `Add Memory` - Add a new memory to your collection
+- `Search Memories` - Search through your existing memories
+
+## Authentication
+
+This extension requires a Supermemory API key. You can get your API key from [supermemory.link/raycast](https://supermemory.link/raycast).
+
+The API key is stored securely in Raycast preferences and is required for all operations. \ No newline at end of file
diff --git a/apps/raycast-extension/assets/extension-icon.png b/apps/raycast-extension/assets/extension-icon.png
new file mode 100644
index 00000000..6e3aafb9
--- /dev/null
+++ b/apps/raycast-extension/assets/extension-icon.png
Binary files differ
diff --git a/apps/raycast-extension/eslint.config.js b/apps/raycast-extension/eslint.config.js
new file mode 100644
index 00000000..40cd66ad
--- /dev/null
+++ b/apps/raycast-extension/eslint.config.js
@@ -0,0 +1,4 @@
+const { defineConfig } = require("eslint/config")
+const raycastConfig = require("@raycast/eslint-config")
+
+module.exports = defineConfig([...raycastConfig])
diff --git a/apps/raycast-extension/metadata/supermemory-1.png b/apps/raycast-extension/metadata/supermemory-1.png
new file mode 100644
index 00000000..afea0224
--- /dev/null
+++ b/apps/raycast-extension/metadata/supermemory-1.png
Binary files differ
diff --git a/apps/raycast-extension/metadata/supermemory-2.png b/apps/raycast-extension/metadata/supermemory-2.png
new file mode 100644
index 00000000..4d8dec8d
--- /dev/null
+++ b/apps/raycast-extension/metadata/supermemory-2.png
Binary files differ
diff --git a/apps/raycast-extension/package-lock.json b/apps/raycast-extension/package-lock.json
new file mode 100644
index 00000000..703ef839
--- /dev/null
+++ b/apps/raycast-extension/package-lock.json
@@ -0,0 +1,3233 @@
+{
+ "name": "supermemory",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "supermemory",
+ "license": "MIT",
+ "dependencies": {
+ "@raycast/api": "^1.103.2",
+ "@raycast/utils": "^1.17.0"
+ },
+ "devDependencies": {
+ "@raycast/eslint-config": "^2.0.4",
+ "@types/node": "22.13.10",
+ "@types/react": "19.0.10",
+ "eslint": "^9.22.0",
+ "prettier": "^3.5.3",
+ "typescript": "^5.8.2"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.10.tgz",
+ "integrity": "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.10.tgz",
+ "integrity": "sha512-dQAxF1dW1C3zpeCDc5KqIYuZ1tgAdRXNoZP7vkBIRtKZPYe2xVr/d3SkirklCHudW1B45tGiUlz2pUWDfbDD4w==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.10.tgz",
+ "integrity": "sha512-LSQa7eDahypv/VO6WKohZGPSJDq5OVOo3UoFR1E4t4Gj1W7zEQMUhI+lo81H+DtB+kP+tDgBp+M4oNCwp6kffg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.10.tgz",
+ "integrity": "sha512-MiC9CWdPrfhibcXwr39p9ha1x0lZJ9KaVfvzA0Wxwz9ETX4v5CHfF09bx935nHlhi+MxhA63dKRRQLiVgSUtEg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.10.tgz",
+ "integrity": "sha512-JC74bdXcQEpW9KkV326WpZZjLguSZ3DfS8wrrvPMHgQOIEIG/sPXEN/V8IssoJhbefLRcRqw6RQH2NnpdprtMA==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.10.tgz",
+ "integrity": "sha512-tguWg1olF6DGqzws97pKZ8G2L7Ig1vjDmGTwcTuYHbuU6TTjJe5FXbgs5C1BBzHbJ2bo1m3WkQDbWO2PvamRcg==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.10.tgz",
+ "integrity": "sha512-3ZioSQSg1HT2N05YxeJWYR+Libe3bREVSdWhEEgExWaDtyFbbXWb49QgPvFH8u03vUPX10JhJPcz7s9t9+boWg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.10.tgz",
+ "integrity": "sha512-LLgJfHJk014Aa4anGDbh8bmI5Lk+QidDmGzuC2D+vP7mv/GeSN+H39zOf7pN5N8p059FcOfs2bVlrRr4SK9WxA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.10.tgz",
+ "integrity": "sha512-oR31GtBTFYCqEBALI9r6WxoU/ZofZl962pouZRTEYECvNF/dtXKku8YXcJkhgK/beU+zedXfIzHijSRapJY3vg==",
+ "cpu": [
+ "arm"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.10.tgz",
+ "integrity": "sha512-5luJWN6YKBsawd5f9i4+c+geYiVEw20FVW5x0v1kEMWNq8UctFjDiMATBxLvmmHA4bf7F6hTRaJgtghFr9iziQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.10.tgz",
+ "integrity": "sha512-NrSCx2Kim3EnnWgS4Txn0QGt0Xipoumb6z6sUtl5bOEZIVKhzfyp/Lyw4C1DIYvzeW/5mWYPBFJU3a/8Yr75DQ==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.10.tgz",
+ "integrity": "sha512-xoSphrd4AZda8+rUDDfD9J6FUMjrkTz8itpTITM4/xgerAZZcFW7Dv+sun7333IfKxGG8gAq+3NbfEMJfiY+Eg==",
+ "cpu": [
+ "loong64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.10.tgz",
+ "integrity": "sha512-ab6eiuCwoMmYDyTnyptoKkVS3k8fy/1Uvq7Dj5czXI6DF2GqD2ToInBI0SHOp5/X1BdZ26RKc5+qjQNGRBelRA==",
+ "cpu": [
+ "mips64el"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.10.tgz",
+ "integrity": "sha512-NLinzzOgZQsGpsTkEbdJTCanwA5/wozN9dSgEl12haXJBzMTpssebuXR42bthOF3z7zXFWH1AmvWunUCkBE4EA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.10.tgz",
+ "integrity": "sha512-FE557XdZDrtX8NMIeA8LBJX3dC2M8VGXwfrQWU7LB5SLOajfJIxmSdyL/gU1m64Zs9CBKvm4UAuBp5aJ8OgnrA==",
+ "cpu": [
+ "riscv64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.10.tgz",
+ "integrity": "sha512-3BBSbgzuB9ajLoVZk0mGu+EHlBwkusRmeNYdqmznmMc9zGASFjSsxgkNsqmXugpPk00gJ0JNKh/97nxmjctdew==",
+ "cpu": [
+ "s390x"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.10.tgz",
+ "integrity": "sha512-QSX81KhFoZGwenVyPoberggdW1nrQZSvfVDAIUXr3WqLRZGZqWk/P4T8p2SP+de2Sr5HPcvjhcJzEiulKgnxtA==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.10.tgz",
+ "integrity": "sha512-AKQM3gfYfSW8XRk8DdMCzaLUFB15dTrZfnX8WXQoOUpUBQ+NaAFCP1kPS/ykbbGYz7rxn0WS48/81l9hFl3u4A==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.10.tgz",
+ "integrity": "sha512-7RTytDPGU6fek/hWuN9qQpeGPBZFfB4zZgcz2VK2Z5VpdUxEI8JKYsg3JfO0n/Z1E/6l05n0unDCNc4HnhQGig==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.10.tgz",
+ "integrity": "sha512-5Se0VM9Wtq797YFn+dLimf2Zx6McttsH2olUBsDml+lm0GOCRVebRWUvDtkY4BWYv/3NgzS8b/UM3jQNh5hYyw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.10.tgz",
+ "integrity": "sha512-XkA4frq1TLj4bEMB+2HnI0+4RnjbuGZfet2gs/LNs5Hc7D89ZQBHQ0gL2ND6Lzu1+QVkjp3x1gIcPKzRNP8bXw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.10.tgz",
+ "integrity": "sha512-AVTSBhTX8Y/Fz6OmIVBip9tJzZEUcY8WLh7I59+upa5/GPhh2/aM6bvOMQySspnCCHvFi79kMtdJS1w0DXAeag==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.10.tgz",
+ "integrity": "sha512-fswk3XT0Uf2pGJmOpDB7yknqhVkJQkAQOcW/ccVOtfx05LkbWOaRAtn5SaqXypeKQra1QaEa841PgrSL9ubSPQ==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.10.tgz",
+ "integrity": "sha512-ah+9b59KDTSfpaCg6VdJoOQvKjI33nTaQr4UluQwW7aEwZQsbMCfTmfEO4VyewOxx4RaDT/xCy9ra2GPWmO7Kw==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.10.tgz",
+ "integrity": "sha512-QHPDbKkrGO8/cz9LKVnJU22HOi4pxZnZhhA2HYHez5Pz4JeffhDjf85E57Oyco163GnzNCVkZK0b/n4Y0UHcSw==",
+ "cpu": [
+ "ia32"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.10.tgz",
+ "integrity": "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw==",
+ "cpu": [
+ "x64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz",
+ "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.0.tgz",
+ "integrity": "sha512-ENIdc4iLu0d93HeYirvKmrzshzofPw6VkZRKQGe9Nv46ZnWUzcF1xV01dcvEg/1wXUR61OmmlSfyeyO7EvjLxQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.6",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.3.1.tgz",
+ "integrity": "sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz",
+ "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
+ "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.12.4",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.0",
+ "minimatch": "^3.1.2",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.36.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.36.0.tgz",
+ "integrity": "sha512-uhCbYtYynH30iZErszX78U+nR3pJU3RHGQ57NXy5QupD4SBVwDeU8TNBy+MjMngc1UyIW9noKqsRqfjQTBU2dw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
+ "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz",
+ "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.15.2",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
+ "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.4.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@inquirer/ansi": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.0.tgz",
+ "integrity": "sha512-JWaTfCxI1eTmJ1BIv86vUfjVatOdxwD0DAVKYevY8SazeUUZtW+tNbsdejVO1GYE0GXJW1N1ahmiC3TFd+7wZA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@inquirer/checkbox": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.2.4.tgz",
+ "integrity": "sha512-2n9Vgf4HSciFq8ttKXk+qy+GsyTXPV1An6QAwe/8bkbbqvG4VW1I/ZY1pNu2rf+h9bdzMLPbRSfcNxkHBy/Ydw==",
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^1.0.0",
+ "@inquirer/core": "^10.2.2",
+ "@inquirer/figures": "^1.0.13",
+ "@inquirer/type": "^3.0.8",
+ "yoctocolors-cjs": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/confirm": {
+ "version": "5.1.18",
+ "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.18.tgz",
+ "integrity": "sha512-MilmWOzHa3Ks11tzvuAmFoAd/wRuaP3SwlT1IZhyMke31FKLxPiuDWcGXhU+PKveNOpAc4axzAgrgxuIJJRmLw==",
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^10.2.2",
+ "@inquirer/type": "^3.0.8"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/core": {
+ "version": "10.2.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.2.2.tgz",
+ "integrity": "sha512-yXq/4QUnk4sHMtmbd7irwiepjB8jXU0kkFRL4nr/aDBA2mDz13cMakEWdDwX3eSCTkk03kwcndD1zfRAIlELxA==",
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^1.0.0",
+ "@inquirer/figures": "^1.0.13",
+ "@inquirer/type": "^3.0.8",
+ "cli-width": "^4.1.0",
+ "mute-stream": "^2.0.0",
+ "signal-exit": "^4.1.0",
+ "wrap-ansi": "^6.2.0",
+ "yoctocolors-cjs": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/core/node_modules/wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@inquirer/editor": {
+ "version": "4.2.20",
+ "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.20.tgz",
+ "integrity": "sha512-7omh5y5bK672Q+Brk4HBbnHNowOZwrb/78IFXdrEB9PfdxL3GudQyDk8O9vQ188wj3xrEebS2M9n18BjJoI83g==",
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^10.2.2",
+ "@inquirer/external-editor": "^1.0.2",
+ "@inquirer/type": "^3.0.8"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/expand": {
+ "version": "4.0.20",
+ "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.20.tgz",
+ "integrity": "sha512-Dt9S+6qUg94fEvgn54F2Syf0Z3U8xmnBI9ATq2f5h9xt09fs2IJXSCIXyyVHwvggKWFXEY/7jATRo2K6Dkn6Ow==",
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^10.2.2",
+ "@inquirer/type": "^3.0.8",
+ "yoctocolors-cjs": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/external-editor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.2.tgz",
+ "integrity": "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==",
+ "license": "MIT",
+ "dependencies": {
+ "chardet": "^2.1.0",
+ "iconv-lite": "^0.7.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/figures": {
+ "version": "1.0.13",
+ "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz",
+ "integrity": "sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@inquirer/input": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.4.tgz",
+ "integrity": "sha512-cwSGpLBMwpwcZZsc6s1gThm0J+it/KIJ+1qFL2euLmSKUMGumJ5TcbMgxEjMjNHRGadouIYbiIgruKoDZk7klw==",
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^10.2.2",
+ "@inquirer/type": "^3.0.8"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/number": {
+ "version": "3.0.20",
+ "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.20.tgz",
+ "integrity": "sha512-bbooay64VD1Z6uMfNehED2A2YOPHSJnQLs9/4WNiV/EK+vXczf/R988itL2XLDGTgmhMF2KkiWZo+iEZmc4jqg==",
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^10.2.2",
+ "@inquirer/type": "^3.0.8"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/password": {
+ "version": "4.0.20",
+ "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.20.tgz",
+ "integrity": "sha512-nxSaPV2cPvvoOmRygQR+h0B+Av73B01cqYLcr7NXcGXhbmsYfUb8fDdw2Us1bI2YsX+VvY7I7upgFYsyf8+Nug==",
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^1.0.0",
+ "@inquirer/core": "^10.2.2",
+ "@inquirer/type": "^3.0.8"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/prompts": {
+ "version": "7.8.6",
+ "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.8.6.tgz",
+ "integrity": "sha512-68JhkiojicX9SBUD8FE/pSKbOKtwoyaVj1kwqLfvjlVXZvOy3iaSWX4dCLsZyYx/5Ur07Fq+yuDNOen+5ce6ig==",
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/checkbox": "^4.2.4",
+ "@inquirer/confirm": "^5.1.18",
+ "@inquirer/editor": "^4.2.20",
+ "@inquirer/expand": "^4.0.20",
+ "@inquirer/input": "^4.2.4",
+ "@inquirer/number": "^3.0.20",
+ "@inquirer/password": "^4.0.20",
+ "@inquirer/rawlist": "^4.1.8",
+ "@inquirer/search": "^3.1.3",
+ "@inquirer/select": "^4.3.4"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/rawlist": {
+ "version": "4.1.8",
+ "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.8.tgz",
+ "integrity": "sha512-CQ2VkIASbgI2PxdzlkeeieLRmniaUU1Aoi5ggEdm6BIyqopE9GuDXdDOj9XiwOqK5qm72oI2i6J+Gnjaa26ejg==",
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^10.2.2",
+ "@inquirer/type": "^3.0.8",
+ "yoctocolors-cjs": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/search": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.1.3.tgz",
+ "integrity": "sha512-D5T6ioybJJH0IiSUK/JXcoRrrm8sXwzrVMjibuPs+AgxmogKslaafy1oxFiorNI4s3ElSkeQZbhYQgLqiL8h6Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/core": "^10.2.2",
+ "@inquirer/figures": "^1.0.13",
+ "@inquirer/type": "^3.0.8",
+ "yoctocolors-cjs": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/select": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.3.4.tgz",
+ "integrity": "sha512-Qp20nySRmfbuJBBsgPU7E/cL62Hf250vMZRzYDcBHty2zdD1kKCnoDFWRr0WO2ZzaXp3R7a4esaVGJUx0E6zvA==",
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/ansi": "^1.0.0",
+ "@inquirer/core": "^10.2.2",
+ "@inquirer/figures": "^1.0.13",
+ "@inquirer/type": "^3.0.8",
+ "yoctocolors-cjs": "^2.1.2"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@inquirer/type": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.8.tgz",
+ "integrity": "sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "@types/node": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@oclif/core": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/@oclif/core/-/core-4.5.4.tgz",
+ "integrity": "sha512-78YYJls8+KG96tReyUsesKKIKqC0qbFSY1peUSrt0P2uGsrgAuU9axQ0iBQdhAlIwZDcTyaj+XXVQkz2kl/O0w==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-escapes": "^4.3.2",
+ "ansis": "^3.17.0",
+ "clean-stack": "^3.0.1",
+ "cli-spinners": "^2.9.2",
+ "debug": "^4.4.3",
+ "ejs": "^3.1.10",
+ "get-package-type": "^0.1.0",
+ "indent-string": "^4.0.0",
+ "is-wsl": "^2.2.0",
+ "lilconfig": "^3.1.3",
+ "minimatch": "^9.0.5",
+ "semver": "^7.6.3",
+ "string-width": "^4.2.3",
+ "supports-color": "^8",
+ "tinyglobby": "^0.2.14",
+ "widest-line": "^3.1.0",
+ "wordwrap": "^1.0.0",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@oclif/plugin-autocomplete": {
+ "version": "3.2.35",
+ "resolved": "https://registry.npmjs.org/@oclif/plugin-autocomplete/-/plugin-autocomplete-3.2.35.tgz",
+ "integrity": "sha512-cwvq1+tQnSHNQEQrop82W7AZIFXC5ENUvicXWhBSpVF1KDIUez/ptIth4M4zha/0+DlSPsYcQgzaN6tSWtUoEA==",
+ "license": "MIT",
+ "dependencies": {
+ "@oclif/core": "^4",
+ "ansis": "^3.16.0",
+ "debug": "^4.4.1",
+ "ejs": "^3.1.10"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@oclif/plugin-help": {
+ "version": "6.2.33",
+ "resolved": "https://registry.npmjs.org/@oclif/plugin-help/-/plugin-help-6.2.33.tgz",
+ "integrity": "sha512-9L07S61R0tuXrURdLcVtjF79Nbyv3qGplJ88DVskJBxShbROZl3hBG7W/CNltAK3cnMPlXV8K3kKh+C0N0p4xw==",
+ "license": "MIT",
+ "dependencies": {
+ "@oclif/core": "^4"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@oclif/plugin-not-found": {
+ "version": "3.2.68",
+ "resolved": "https://registry.npmjs.org/@oclif/plugin-not-found/-/plugin-not-found-3.2.68.tgz",
+ "integrity": "sha512-Uv0AiXESEwrIbfN1IA68lcw4/7/L+Z3nFHMHG03jjDXHTVOfpTZDaKyPx/6rf2AL/CIhQQxQF3foDvs6psS3tA==",
+ "license": "MIT",
+ "dependencies": {
+ "@inquirer/prompts": "^7.8.4",
+ "@oclif/core": "^4.5.3",
+ "ansis": "^3.17.0",
+ "fast-levenshtein": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@raycast/api": {
+ "version": "1.103.2",
+ "resolved": "https://registry.npmjs.org/@raycast/api/-/api-1.103.2.tgz",
+ "integrity": "sha512-5QTKMRv86t0cUFH9a07ne8a+ry8bZ2xtOd7trx3yiMmJREr5edYXsqcGDsOyeJLjrjH7WhoRlESIW/CHgNwg8w==",
+ "license": "MIT",
+ "dependencies": {
+ "@oclif/core": "^4.4.1",
+ "@oclif/plugin-autocomplete": "^3.2.31",
+ "@oclif/plugin-help": "^6.2.29",
+ "@oclif/plugin-not-found": "^3.2.57",
+ "@types/node": "22.13.10",
+ "@types/react": "19.0.10",
+ "esbuild": "^0.25.5",
+ "react": "19.0.0"
+ },
+ "bin": {
+ "ray": "bin/run.js"
+ },
+ "engines": {
+ "node": ">=22.14.0"
+ },
+ "peerDependencies": {
+ "@types/node": "22.13.10",
+ "@types/react": "19.0.10",
+ "react-devtools": "6.1.1"
+ },
+ "peerDependenciesMeta": {
+ "@types/node": {
+ "optional": true
+ },
+ "@types/react": {
+ "optional": true
+ },
+ "react-devtools": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@raycast/eslint-config": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/@raycast/eslint-config/-/eslint-config-2.0.4.tgz",
+ "integrity": "sha512-Sz5Q0HVY8pW21Sv7CDcJw882OGubSM3zx5uiDRQMkgt7Hui3I+IZOqxDInnhLsGG52prSdU7sg3R097hMJkkQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint/js": "^9.22.0",
+ "@raycast/eslint-plugin": "^2.0.4",
+ "eslint-config-prettier": "^10.1.1",
+ "globals": "^16.0.0",
+ "typescript-eslint": "^8.26.1"
+ },
+ "peerDependencies": {
+ "eslint": ">=8.23.0",
+ "prettier": ">=2",
+ "typescript": ">=4"
+ }
+ },
+ "node_modules/@raycast/eslint-plugin": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@raycast/eslint-plugin/-/eslint-plugin-2.0.7.tgz",
+ "integrity": "sha512-4dAdua+TFQu7ay3EuDmg5nT7boIAj3Rjf0V1aQ3w5uAx/j98DvI91h/zbbkVb4mIXCom1w7SfRrZQzYIOE+tZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/utils": "^8.26.1"
+ },
+ "peerDependencies": {
+ "eslint": ">=8.23.0"
+ }
+ },
+ "node_modules/@raycast/utils": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/@raycast/utils/-/utils-1.19.1.tgz",
+ "integrity": "sha512-/udUGcTZCgZZwzesmjBkqG5naQZTD/ZLHbqRwkWcF+W97vf9tr9raxKyQjKsdZ17OVllw2T3sHBQsVUdEmCm2g==",
+ "license": "MIT",
+ "dependencies": {
+ "cross-fetch": "^3.1.6",
+ "dequal": "^2.0.3",
+ "object-hash": "^3.0.0",
+ "signal-exit": "^4.0.2",
+ "stream-chain": "^2.2.5",
+ "stream-json": "^1.8.0"
+ },
+ "peerDependencies": {
+ "@raycast/api": ">=1.69.0"
+ }
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "22.13.10",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.20.0"
+ }
+ },
+ "node_modules/@types/node/node_modules/undici-types": {
+ "version": "6.20.0",
+ "license": "MIT"
+ },
+ "node_modules/@types/react": {
+ "version": "19.0.10",
+ "license": "MIT",
+ "dependencies": {
+ "csstype": "^3.0.2"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.44.1.tgz",
+ "integrity": "sha512-molgphGqOBT7t4YKCSkbasmu1tb1MgrZ2szGzHbclF7PNmOkSTQVHy+2jXOSnxvR3+Xe1yySHFZoqMpz3TfQsw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "8.44.1",
+ "@typescript-eslint/type-utils": "8.44.1",
+ "@typescript-eslint/utils": "8.44.1",
+ "@typescript-eslint/visitor-keys": "8.44.1",
+ "graphemer": "^1.4.0",
+ "ignore": "^7.0.0",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.44.1",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.44.1.tgz",
+ "integrity": "sha512-EHrrEsyhOhxYt8MTg4zTF+DJMuNBzWwgvvOYNj/zm1vnaD/IC5zCXFehZv94Piqa2cRFfXrTFxIvO95L7Qc/cw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.44.1",
+ "@typescript-eslint/types": "8.44.1",
+ "@typescript-eslint/typescript-estree": "8.44.1",
+ "@typescript-eslint/visitor-keys": "8.44.1",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.44.1.tgz",
+ "integrity": "sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.44.1",
+ "@typescript-eslint/types": "^8.44.1",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.44.1.tgz",
+ "integrity": "sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.44.1",
+ "@typescript-eslint/visitor-keys": "8.44.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.44.1.tgz",
+ "integrity": "sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.44.1.tgz",
+ "integrity": "sha512-KdEerZqHWXsRNKjF9NYswNISnFzXfXNDfPxoTh7tqohU/PRIbwTmsjGK6V9/RTYWau7NZvfo52lgVk+sJh0K3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.44.1",
+ "@typescript-eslint/typescript-estree": "8.44.1",
+ "@typescript-eslint/utils": "8.44.1",
+ "debug": "^4.3.4",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.44.1.tgz",
+ "integrity": "sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.44.1.tgz",
+ "integrity": "sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.44.1",
+ "@typescript-eslint/tsconfig-utils": "8.44.1",
+ "@typescript-eslint/types": "8.44.1",
+ "@typescript-eslint/visitor-keys": "8.44.1",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^2.1.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.44.1.tgz",
+ "integrity": "sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.7.0",
+ "@typescript-eslint/scope-manager": "8.44.1",
+ "@typescript-eslint/types": "8.44.1",
+ "@typescript-eslint/typescript-estree": "8.44.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.44.1.tgz",
+ "integrity": "sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.44.1",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.15.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
+ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
+ "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.21.3"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/ansis": {
+ "version": "3.17.0",
+ "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.17.0.tgz",
+ "integrity": "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/async": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
+ "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==",
+ "license": "MIT"
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "license": "MIT"
+ },
+ "node_modules/brace-expansion": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
+ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/chalk/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/chardet": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz",
+ "integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==",
+ "license": "MIT"
+ },
+ "node_modules/clean-stack": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz",
+ "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==",
+ "license": "MIT",
+ "dependencies": {
+ "escape-string-regexp": "4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-spinners": {
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
+ "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-width": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz",
+ "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==",
+ "license": "ISC",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "license": "MIT"
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cross-fetch": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.2.0.tgz",
+ "integrity": "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==",
+ "license": "MIT",
+ "dependencies": {
+ "node-fetch": "^2.7.0"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/csstype": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/dequal": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/ejs": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz",
+ "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "jake": "^10.8.5"
+ },
+ "bin": {
+ "ejs": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "license": "MIT"
+ },
+ "node_modules/esbuild": {
+ "version": "0.25.10",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.10.tgz",
+ "integrity": "sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.25.10",
+ "@esbuild/android-arm": "0.25.10",
+ "@esbuild/android-arm64": "0.25.10",
+ "@esbuild/android-x64": "0.25.10",
+ "@esbuild/darwin-arm64": "0.25.10",
+ "@esbuild/darwin-x64": "0.25.10",
+ "@esbuild/freebsd-arm64": "0.25.10",
+ "@esbuild/freebsd-x64": "0.25.10",
+ "@esbuild/linux-arm": "0.25.10",
+ "@esbuild/linux-arm64": "0.25.10",
+ "@esbuild/linux-ia32": "0.25.10",
+ "@esbuild/linux-loong64": "0.25.10",
+ "@esbuild/linux-mips64el": "0.25.10",
+ "@esbuild/linux-ppc64": "0.25.10",
+ "@esbuild/linux-riscv64": "0.25.10",
+ "@esbuild/linux-s390x": "0.25.10",
+ "@esbuild/linux-x64": "0.25.10",
+ "@esbuild/netbsd-arm64": "0.25.10",
+ "@esbuild/netbsd-x64": "0.25.10",
+ "@esbuild/openbsd-arm64": "0.25.10",
+ "@esbuild/openbsd-x64": "0.25.10",
+ "@esbuild/openharmony-arm64": "0.25.10",
+ "@esbuild/sunos-x64": "0.25.10",
+ "@esbuild/win32-arm64": "0.25.10",
+ "@esbuild/win32-ia32": "0.25.10",
+ "@esbuild/win32-x64": "0.25.10"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.36.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.36.0.tgz",
+ "integrity": "sha512-hB4FIzXovouYzwzECDcUkJ4OcfOEkXTv2zRY6B9bkwjx/cprAq0uvm1nl7zvQ0/TsUk0zQiN4uPfJpB9m+rPMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.0",
+ "@eslint/config-helpers": "^0.3.1",
+ "@eslint/core": "^0.15.2",
+ "@eslint/eslintrc": "^3.3.1",
+ "@eslint/js": "9.36.0",
+ "@eslint/plugin-kit": "^0.3.5",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
+ "ajv": "^6.12.4",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.2",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "10.1.8",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz",
+ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-config-prettier"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/eslint/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/espree/node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.8"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-glob/node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz",
+ "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "fastest-levenshtein": "^1.0.7"
+ }
+ },
+ "node_modules/fastest-levenshtein": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.9.1"
+ }
+ },
+ "node_modules/fastq": {
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/filelist": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz",
+ "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "minimatch": "^5.0.1"
+ }
+ },
+ "node_modules/filelist/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/get-package-type": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz",
+ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/globals": {
+ "version": "16.4.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz",
+ "integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graphemer": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
+ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz",
+ "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-docker": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
+ "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
+ "license": "MIT",
+ "bin": {
+ "is-docker": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-wsl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
+ "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
+ "license": "MIT",
+ "dependencies": {
+ "is-docker": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/jake": {
+ "version": "10.9.4",
+ "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz",
+ "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "async": "^3.2.6",
+ "filelist": "^1.0.4",
+ "picocolors": "^1.1.1"
+ },
+ "bin": {
+ "jake": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lilconfig": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "braces": "^3.0.3",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/mute-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz",
+ "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==",
+ "license": "ISC",
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/object-hash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
+ "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/optionator/node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
+ "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/react": {
+ "version": "19.0.0",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.0.0.tgz",
+ "integrity": "sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
+ },
+ "node_modules/semver": {
+ "version": "7.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
+ "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/stream-chain": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz",
+ "integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==",
+ "license": "BSD-3-Clause"
+ },
+ "node_modules/stream-json": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.9.1.tgz",
+ "integrity": "sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "stream-chain": "^2.2.5"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+ "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.15",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
+ "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinyglobby/node_modules/fdir": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tinyglobby/node_modules/picomatch": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
+ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "license": "MIT"
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+ "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "0.21.3",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
+ "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.9.2",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.44.1",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.44.1.tgz",
+ "integrity": "sha512-0ws8uWGrUVTjEeN2OM4K1pLKHK/4NiNP/vz6ns+LjT/6sqpaYzIVFajZb1fj/IDwpsrrHb3Jy0Qm5u9CPcKaeg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.44.1",
+ "@typescript-eslint/parser": "8.44.1",
+ "@typescript-eslint/typescript-estree": "8.44.1",
+ "@typescript-eslint/utils": "8.44.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <6.0.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/widest-line": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz",
+ "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==",
+ "license": "MIT",
+ "dependencies": {
+ "string-width": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/yoctocolors-cjs": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz",
+ "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/apps/raycast-extension/package.json b/apps/raycast-extension/package.json
new file mode 100644
index 00000000..9481601b
--- /dev/null
+++ b/apps/raycast-extension/package.json
@@ -0,0 +1,62 @@
+{
+ "$schema": "https://www.raycast.com/schemas/extension.json",
+ "name": "supermemory",
+ "title": "Supermemory",
+ "description": "Add and search memories with your personal AI-powered knowledge base",
+ "icon": "extension-icon.png",
+ "author": "supermemory",
+ "platforms": [
+ "macOS",
+ "Windows"
+ ],
+ "categories": [
+ "Productivity",
+ "Web"
+ ],
+ "license": "MIT",
+ "commands": [
+ {
+ "name": "add-memory",
+ "title": "Add Memory",
+ "subtitle": "add memory to your supermemory app",
+ "description": "Add text, URLs, or documents to your supermemory knowledge base",
+ "mode": "view"
+ },
+ {
+ "name": "search-memories",
+ "title": "Search Memories",
+ "description": "Search through your saved memories and find relevant information",
+ "mode": "view"
+ }
+ ],
+ "preferences": [
+ {
+ "name": "apiKey",
+ "type": "password",
+ "required": true,
+ "title": "API Key",
+ "description": "Your Supermemory API Key. Get it from https://supermemory.link/raycast",
+ "placeholder": "Enter your Supermemory API Key"
+ }
+ ],
+ "dependencies": {
+ "@raycast/api": "^1.103.2",
+ "@raycast/utils": "^1.17.0"
+ },
+ "devDependencies": {
+ "@raycast/eslint-config": "^2.0.4",
+ "@types/node": "22.13.10",
+ "@types/react": "19.0.10",
+ "eslint": "^9.22.0",
+ "prettier": "^3.5.3",
+ "typescript": "^5.8.2"
+ },
+ "scripts": {
+ "build": "ray build",
+ "dev": "ray develop",
+ "fix-lint": "ray lint --fix",
+ "lint": "ray lint",
+ "prepublishOnly": "echo \"\\n\\nIt seems like you are trying to publish the Raycast extension to npm.\\n\\nIf you did intend to publish it to npm, remove the \\`prepublishOnly\\` script and rerun \\`npm publish\\` again.\\nIf you wanted to publish it to the Raycast Store instead, use \\`npm run publish\\` instead.\\n\\n\" && exit 1",
+ "publish": "npx @raycast/api@latest publish"
+ }
+} \ No newline at end of file
diff --git a/apps/raycast-extension/src/add-memory.tsx b/apps/raycast-extension/src/add-memory.tsx
new file mode 100644
index 00000000..87fb853f
--- /dev/null
+++ b/apps/raycast-extension/src/add-memory.tsx
@@ -0,0 +1,110 @@
+import {
+ Form,
+ ActionPanel,
+ Action,
+ showToast,
+ Toast,
+ useNavigation,
+} from "@raycast/api";
+import { useEffect, useState } from "react";
+import {
+ addMemory,
+ fetchProjects,
+ checkApiConnection,
+ type Project,
+} from "./api";
+
+interface FormValues {
+ content: string;
+ project: string;
+}
+
+export default function Command() {
+ const [projects, setProjects] = useState<Project[]>([]);
+ const [isLoading, setIsLoading] = useState(true);
+ const [isSubmitting, setIsSubmitting] = useState(false);
+ const { pop } = useNavigation();
+
+ useEffect(() => {
+ async function loadProjects() {
+ try {
+ setIsLoading(true);
+ const isConnected = await checkApiConnection();
+ if (!isConnected) {
+ return;
+ }
+
+ const fetchedProjects = await fetchProjects();
+ setProjects(fetchedProjects);
+ } catch (error) {
+ console.error("Failed to load projects:", error);
+ } finally {
+ setIsLoading(false);
+ }
+ }
+
+ loadProjects();
+ }, []);
+
+ async function handleSubmit(values: FormValues) {
+ if (!values.content.trim()) {
+ await showToast({
+ style: Toast.Style.Failure,
+ title: "Content Required",
+ message: "Please enter some content for the memory",
+ });
+ return;
+ }
+
+ try {
+ setIsSubmitting(true);
+
+ const containerTags = values.project ? [values.project] : undefined;
+
+ await addMemory({
+ content: values.content.trim(),
+ containerTags,
+ });
+
+ pop();
+ } catch (error) {
+ console.error("Failed to add memory:", error);
+ } finally {
+ setIsSubmitting(false);
+ }
+ }
+
+ return (
+ <Form
+ isLoading={isLoading || isSubmitting}
+ actions={
+ <ActionPanel>
+ <Action.SubmitForm title="Add Memory" onSubmit={handleSubmit} />
+ </ActionPanel>
+ }
+ >
+ <Form.TextArea
+ id="content"
+ title="Content"
+ placeholder="Enter the memory content..."
+ info="The main content of your memory. This is required."
+ />
+ <Form.Separator />
+ <Form.Dropdown
+ id="project"
+ title="Project"
+ info="Select a project to organize this memory"
+ storeValue
+ >
+ <Form.Dropdown.Item value="" title="No Project" />
+ {projects.map((project) => (
+ <Form.Dropdown.Item
+ key={project.id}
+ value={project.containerTag}
+ title={project.name}
+ />
+ ))}
+ </Form.Dropdown>
+ </Form>
+ );
+}
diff --git a/apps/raycast-extension/src/api.ts b/apps/raycast-extension/src/api.ts
new file mode 100644
index 00000000..0cb2ec20
--- /dev/null
+++ b/apps/raycast-extension/src/api.ts
@@ -0,0 +1,227 @@
+import { getPreferenceValues, showToast, Toast } from "@raycast/api";
+
+export interface Project {
+ id: string;
+ name: string;
+ containerTag: string;
+ description?: string;
+}
+
+export interface Memory {
+ id: string;
+ content: string;
+ title?: string;
+ url?: string;
+ containerTag?: string;
+ createdAt: string;
+}
+
+export interface SearchResult {
+ documentId: string;
+ chunks: unknown[];
+ title?: string;
+ metadata: Record<string, unknown>;
+ score?: number;
+ createdAt: string;
+ updatedAt: string;
+ type: string;
+}
+
+export interface AddMemoryRequest {
+ content: string;
+ containerTags?: string[];
+ title?: string;
+ url?: string;
+ metadata?: Record<string, unknown>;
+}
+
+export interface SearchRequest {
+ q: string;
+ containerTags?: string[];
+ limit?: number;
+}
+
+export interface SearchResponse {
+ results: SearchResult[];
+ timing: number;
+ total: number;
+}
+
+const API_BASE_URL = "https://api.supermemory.ai";
+
+class SupermemoryAPIError extends Error {
+ constructor(
+ message: string,
+ public status?: number,
+ ) {
+ super(message);
+ this.name = "SupermemoryAPIError";
+ }
+}
+
+class AuthenticationError extends Error {
+ constructor(message: string) {
+ super(message);
+ this.name = "AuthenticationError";
+ }
+}
+
+async function getApiKey(): Promise<string> {
+ try {
+ const preferences = getPreferenceValues<{ apiKey: string }>();
+ const apiKey = preferences.apiKey?.trim();
+
+ if (!apiKey) {
+ throw new AuthenticationError(
+ "API key is required. Please add your Supermemory API key in preferences.",
+ );
+ }
+
+ return apiKey;
+ } catch {
+ throw new AuthenticationError("Failed to get API key from preferences.");
+ }
+}
+
+async function makeAuthenticatedRequest<T>(
+ endpoint: string,
+ options: RequestInit = {},
+): Promise<T> {
+ const apiKey = await getApiKey();
+
+ const url = `${API_BASE_URL}${endpoint}`;
+
+ try {
+ const response = await fetch(url, {
+ ...options,
+ headers: {
+ Authorization: `Bearer ${apiKey}`,
+ "Content-Type": "application/json",
+ ...options.headers,
+ },
+ });
+
+ if (!response.ok) {
+ if (response.status === 401) {
+ throw new AuthenticationError(
+ "Invalid API key. Please check your API key in preferences. Get a new one from https://supermemory.link/raycast",
+ );
+ }
+
+ let errorMessage = `API request failed: ${response.statusText}`;
+ try {
+ const errorBody = (await response.json()) as { message?: string };
+ if (errorBody.message) {
+ errorMessage = errorBody.message;
+ }
+ } catch {
+ // Ignore JSON parsing errors, use default message
+ }
+
+ throw new SupermemoryAPIError(errorMessage, response.status);
+ }
+
+ if (!response.headers.get("content-type")?.includes("application/json")) {
+ throw new SupermemoryAPIError("Invalid response format from API");
+ }
+
+ const data = (await response.json()) as T;
+ return data;
+ } catch (err) {
+ if (
+ err instanceof AuthenticationError ||
+ err instanceof SupermemoryAPIError
+ ) {
+ throw err;
+ }
+
+ // Handle network errors or other fetch errors
+ throw new SupermemoryAPIError(
+ `Network error: ${err instanceof Error ? err.message : "Unknown error"}`,
+ );
+ }
+}
+
+export async function fetchProjects(): Promise<Project[]> {
+ try {
+ const response = await makeAuthenticatedRequest<{ projects: Project[] }>(
+ "/v3/projects",
+ );
+ return response.projects || [];
+ } catch (error) {
+ await showToast({
+ style: Toast.Style.Failure,
+ title: "Failed to fetch projects",
+ message:
+ error instanceof Error ? error.message : "Unknown error occurred",
+ });
+ throw error;
+ }
+}
+
+export async function addMemory(request: AddMemoryRequest): Promise<Memory> {
+ try {
+ const response = await makeAuthenticatedRequest<Memory>("/v3/documents", {
+ method: "POST",
+ body: JSON.stringify(request),
+ });
+
+ await showToast({
+ style: Toast.Style.Success,
+ title: "Memory Added",
+ message: "Successfully added memory to Supermemory",
+ });
+
+ return response;
+ } catch (error) {
+ await showToast({
+ style: Toast.Style.Failure,
+ title: "Failed to add memory",
+ message:
+ error instanceof Error ? error.message : "Unknown error occurred",
+ });
+ throw error;
+ }
+}
+
+export async function searchMemories(
+ request: SearchRequest,
+): Promise<SearchResult[]> {
+ try {
+ const response = await makeAuthenticatedRequest<SearchResponse>(
+ "/v3/search",
+ {
+ method: "POST",
+ body: JSON.stringify(request),
+ },
+ );
+
+ return response.results || [];
+ } catch (error) {
+ await showToast({
+ style: Toast.Style.Failure,
+ title: "Failed to search memories",
+ message:
+ error instanceof Error ? error.message : "Unknown error occurred",
+ });
+ throw error;
+ }
+}
+
+// Helper function to check if API key is configured and valid
+export async function checkApiConnection(): Promise<boolean> {
+ try {
+ await fetchProjects();
+ return true;
+ } catch (error) {
+ if (error instanceof AuthenticationError) {
+ await showToast({
+ style: Toast.Style.Failure,
+ title: "API Key Required",
+ message:
+ "Please configure your Supermemory API key in preferences. Get it from https://supermemory.link/raycast",
+ });
+ }
+ return false;
+ }
+}
diff --git a/apps/raycast-extension/src/search-memories.tsx b/apps/raycast-extension/src/search-memories.tsx
new file mode 100644
index 00000000..850fbe3c
--- /dev/null
+++ b/apps/raycast-extension/src/search-memories.tsx
@@ -0,0 +1,253 @@
+import {
+ ActionPanel,
+ Detail,
+ List,
+ Action,
+ Icon,
+ showToast,
+ Toast,
+ Clipboard,
+ openExtensionPreferences,
+} from "@raycast/api";
+import { useState, useEffect, useCallback } from "react";
+import { searchMemories, checkApiConnection, type SearchResult } from "./api";
+
+const extractContent = (memory: SearchResult) => {
+ if (memory.chunks && memory.chunks.length > 0) {
+ return memory.chunks
+ .map((chunk: unknown) => {
+ if (typeof chunk === "string") return chunk;
+ if (
+ chunk &&
+ typeof chunk === "object" &&
+ "content" in chunk &&
+ typeof chunk.content === "string"
+ )
+ return chunk.content;
+ if (
+ chunk &&
+ typeof chunk === "object" &&
+ "text" in chunk &&
+ typeof chunk.text === "string"
+ )
+ return chunk.text;
+ return "";
+ })
+ .filter(Boolean)
+ .join(" ");
+ }
+ return "No content available";
+};
+
+const extractUrl = (memory: SearchResult) => {
+ if (memory.metadata?.url && typeof memory.metadata.url === "string") {
+ return memory.metadata.url;
+ }
+ return null;
+};
+
+export default function Command() {
+ const [searchResults, setSearchResults] = useState<SearchResult[]>([]);
+ const [isLoading, setIsLoading] = useState(false);
+ const [searchText, setSearchText] = useState("");
+ const [hasSearched, setHasSearched] = useState(false);
+ const [isConnected, setIsConnected] = useState<boolean | null>(null);
+
+ useEffect(() => {
+ async function checkConnection() {
+ const connected = await checkApiConnection();
+ setIsConnected(connected);
+ }
+ checkConnection();
+ }, []);
+
+ const performSearch = useCallback(
+ async (query: string) => {
+ if (!query.trim() || !isConnected) return;
+
+ try {
+ setIsLoading(true);
+ setHasSearched(true);
+
+ const results = await searchMemories({
+ q: query.trim(),
+ limit: 50,
+ });
+
+ setSearchResults(results);
+
+ if (results.length === 0) {
+ await showToast({
+ style: Toast.Style.Success,
+ title: "Search Complete",
+ message: "No memories found for your query",
+ });
+ }
+ } catch (error) {
+ console.error("Search failed:", error);
+ setSearchResults([]);
+ } finally {
+ setIsLoading(false);
+ }
+ },
+ [isConnected],
+ );
+
+ useEffect(() => {
+ if (!searchText.trim()) {
+ setSearchResults([]);
+ setHasSearched(false);
+ return;
+ }
+
+ const debounceTimer = setTimeout(() => {
+ performSearch(searchText);
+ }, 500);
+
+ return () => clearTimeout(debounceTimer);
+ }, [searchText, performSearch]);
+
+ const formatDate = (dateString: string) => {
+ try {
+ return new Date(dateString).toLocaleDateString("en-US", {
+ year: "numeric",
+ month: "short",
+ day: "numeric",
+ hour: "2-digit",
+ minute: "2-digit",
+ });
+ } catch {
+ return "Unknown date";
+ }
+ };
+
+ const truncateContent = (content: string, maxLength = 100) => {
+ if (content.length <= maxLength) return content;
+ return `${content.substring(0, maxLength)}...`;
+ };
+
+ if (isConnected === false) {
+ return (
+ <List>
+ <List.EmptyView
+ icon={Icon.ExclamationMark}
+ title="API Key Required"
+ description="Please configure your Supermemory API key to search memories"
+ actions={
+ <ActionPanel>
+ <Action
+ title="Open Extension Preferences"
+ onAction={() => openExtensionPreferences()}
+ icon={Icon.Gear}
+ />
+ </ActionPanel>
+ }
+ />
+ </List>
+ );
+ }
+
+ return (
+ <List
+ isLoading={isLoading}
+ onSearchTextChange={setSearchText}
+ searchBarPlaceholder="Search your memories..."
+ throttle
+ >
+ {!hasSearched && !searchText.trim() ? (
+ <List.EmptyView
+ icon={Icon.MagnifyingGlass}
+ title="Search Your Memories"
+ description="Type to search through your Supermemory collection"
+ />
+ ) : hasSearched && searchResults.length === 0 ? (
+ <List.EmptyView
+ icon={Icon.Document}
+ title="No Memories Found"
+ description={`No memories found for "${searchText}"`}
+ />
+ ) : (
+ searchResults.map((memory) => {
+ const content = extractContent(memory);
+ const url = extractUrl(memory);
+ return (
+ <List.Item
+ key={memory.documentId}
+ icon={url ? Icon.Link : Icon.Document}
+ title={memory.title || "Untitled Memory"}
+ subtitle={truncateContent(content)}
+ accessories={[
+ { text: formatDate(memory.createdAt) },
+ ...(memory.score
+ ? [{ text: `${Math.round(memory.score * 100)}%` }]
+ : []),
+ ]}
+ actions={
+ <ActionPanel>
+ <Action.Push
+ title="View Details"
+ target={<MemoryDetail memory={memory} />}
+ icon={Icon.Eye}
+ />
+ <Action
+ title="Copy Content"
+ onAction={() => Clipboard.copy(content)}
+ icon={Icon.Clipboard}
+ shortcut={{ modifiers: ["cmd"], key: "c" }}
+ />
+ {url && (
+ <Action.OpenInBrowser
+ title="Open URL"
+ url={url}
+ shortcut={{ modifiers: ["cmd"], key: "o" }}
+ />
+ )}
+ </ActionPanel>
+ }
+ />
+ );
+ })
+ )}
+ </List>
+ );
+}
+
+function MemoryDetail({ memory }: { memory: SearchResult }) {
+ const content = extractContent(memory);
+ const url = extractUrl(memory);
+
+ const markdown = `
+# ${memory.title || "Untitled Memory"}
+
+${content}
+
+---
+
+**Created:** ${new Date(memory.createdAt).toLocaleString()}
+${url ? `**URL:** ${url}` : ""}
+${memory.score ? `**Relevance:** ${Math.round(memory.score * 100)}%` : ""}
+`;
+
+ return (
+ <Detail
+ markdown={markdown}
+ actions={
+ <ActionPanel>
+ <Action
+ title="Copy Content"
+ onAction={() => Clipboard.copy(content)}
+ icon={Icon.Clipboard}
+ shortcut={{ modifiers: ["cmd"], key: "c" }}
+ />
+ {url && (
+ <Action.OpenInBrowser
+ title="Open URL"
+ url={url}
+ shortcut={{ modifiers: ["cmd"], key: "o" }}
+ />
+ )}
+ </ActionPanel>
+ }
+ />
+ );
+}
diff --git a/apps/raycast-extension/tsconfig.json b/apps/raycast-extension/tsconfig.json
new file mode 100644
index 00000000..d33dd46c
--- /dev/null
+++ b/apps/raycast-extension/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "$schema": "https://json.schemastore.org/tsconfig",
+ "include": ["src/**/*", "raycast-env.d.ts"],
+ "compilerOptions": {
+ "lib": ["ES2023"],
+ "module": "commonjs",
+ "target": "ES2023",
+ "strict": true,
+ "isolatedModules": true,
+ "esModuleInterop": true,
+ "skipLibCheck": true,
+ "forceConsistentCasingInFileNames": true,
+ "jsx": "react-jsx",
+ "resolveJsonModule": true
+ }
+}
diff --git a/apps/web/app/(navigation)/page.tsx b/apps/web/app/(navigation)/page.tsx
index b8c81985..d2be1ad8 100644
--- a/apps/web/app/(navigation)/page.tsx
+++ b/apps/web/app/(navigation)/page.tsx
@@ -6,6 +6,7 @@ import { ChevronsDown, LoaderIcon } from "lucide-react"
import { useRouter } from "next/navigation"
import { useEffect } from "react"
import { InstallPrompt } from "@/components/install-prompt"
+import { ChromeExtensionButton } from "@/components/chrome-extension-button"
import { ChatInput } from "@/components/chat-input"
import { BackgroundPlus } from "@ui/components/grid-plus"
import { Memories } from "@/components/memories"
@@ -76,6 +77,7 @@ export default function Page() {
<Memories />
<InstallPrompt />
+ <ChromeExtensionButton />
</div>
)
}
diff --git a/apps/web/components/chrome-extension-button.tsx b/apps/web/components/chrome-extension-button.tsx
new file mode 100644
index 00000000..5fd58cac
--- /dev/null
+++ b/apps/web/components/chrome-extension-button.tsx
@@ -0,0 +1,234 @@
+"use client"
+
+import { Button } from "@ui/components/button"
+import {
+ Bookmark,
+ Zap,
+ CircleX,
+ Users,
+ Lock,
+ ChromeIcon,
+ TwitterIcon,
+} from "lucide-react"
+import { useEffect, useState } from "react"
+import { motion } from "framer-motion"
+import Image from "next/image"
+import { analytics } from "@/lib/analytics"
+
+export function ChromeExtensionButton() {
+ const [isExtensionInstalled, setIsExtensionInstalled] = useState(false)
+ const [isChecking, setIsChecking] = useState(true)
+ const [isDismissed, setIsDismissed] = useState(false)
+ const [isMinimized, setIsMinimized] = useState(false)
+
+ useEffect(() => {
+ const dismissed =
+ localStorage.getItem("chrome-extension-dismissed") === "true"
+ setIsDismissed(dismissed)
+
+ const checkExtension = () => {
+ const message = { action: "check-extension" }
+
+ const timeout = setTimeout(() => {
+ setIsExtensionInstalled(false)
+ setIsChecking(false)
+ // Auto-minimize after 3 seconds if extension is not installed and not dismissed
+ if (!dismissed) {
+ setTimeout(() => {
+ setIsMinimized(true)
+ }, 3000)
+ }
+ }, 1000)
+
+ const handleMessage = (event: MessageEvent) => {
+ if (event.data?.action === "extension-detected") {
+ clearTimeout(timeout)
+ setIsExtensionInstalled(true)
+ setIsChecking(false)
+ window.removeEventListener("message", handleMessage)
+ }
+ }
+
+ window.addEventListener("message", handleMessage)
+
+ window.postMessage(message, "*")
+
+ return () => {
+ clearTimeout(timeout)
+ window.removeEventListener("message", handleMessage)
+ }
+ }
+
+ if (!dismissed) {
+ checkExtension()
+ } else {
+ setIsChecking(false)
+ }
+ }, [])
+
+ const handleInstall = () => {
+ analytics.extensionInstallClicked()
+ window.open(
+ "https://chromewebstore.google.com/detail/supermemory/afpgkkipfdpeaflnpoaffkcankadgjfc",
+ "_blank",
+ "noopener,noreferrer",
+ )
+ }
+
+ const handleDismiss = () => {
+ localStorage.setItem("chrome-extension-dismissed", "true")
+ setIsDismissed(true)
+ }
+
+ // Don't show if extension is installed, checking, or dismissed
+ if (isExtensionInstalled || isChecking || isDismissed) {
+ return null
+ }
+
+ return (
+ <motion.div
+ className="fixed bottom-4 right-4 z-50"
+ initial={{ opacity: 0, y: 20, scale: 0.9 }}
+ animate={{ opacity: 1, y: 0, scale: 1 }}
+ transition={{ duration: 0.3, ease: "easeOut" }}
+ >
+ <div
+ className={`bg-background/95 backdrop-blur-md shadow-xl ${
+ isMinimized
+ ? "flex items-center gap-1 rounded-full"
+ : "max-w-md w-90 rounded-2xl"
+ }`}
+ >
+ {!isMinimized && (
+ <motion.div
+ initial={{ opacity: 0, y: 10 }}
+ animate={{ opacity: 1, y: 0 }}
+ exit={{ opacity: 0, y: -10 }}
+ transition={{ duration: 0.3, ease: [0.4, 0, 0.2, 1] }}
+ className="overflow-hidden"
+ >
+ <div className="p-4 text-white bg-cover bg-center">
+ <div
+ className="p-4 rounded-lg"
+ style={{
+ backgroundImage: "url('/images/extension-bg.png')",
+ backgroundSize: "cover",
+ backgroundPosition: "center",
+ backgroundRepeat: "no-repeat",
+ }}
+ >
+ <div className="relative">
+ <h1 className="text-2xl font-bold mb-1">
+ supermemory extension
+ </h1>
+ <p className="text-sm opacity-90">
+ your second brain for the web.
+ </p>
+ </div>
+ </div>
+ </div>
+
+ <div className="px-6 py-2 pb-4 space-y-4">
+ <div className="flex items-start gap-3">
+ <div className="w-10 h-10 bg-blue-50 border border-blue-200 rounded-lg flex items-center justify-center flex-shrink-0">
+ <TwitterIcon className="fill-blue-500 text-blue-500" />
+ </div>
+ <div>
+ <h3 className="font-semibold text-sm text-gray-800">
+ Twitter Imports
+ </h3>
+ <p className="text-xs text-gray-600">
+ Import your twitter timeline & save tweets.
+ </p>
+ </div>
+ </div>
+
+ <div className="flex items-start gap-3">
+ <div className="w-10 h-10 bg-orange-50 border border-orange-200 rounded-lg flex items-center justify-center flex-shrink-0">
+ <Bookmark className="w-5 h-5 text-orange-600" />
+ </div>
+ <div>
+ <h3 className="font-semibold text-sm text-gray-800">
+ Save All Bookmarks
+ </h3>
+ <p className="text-xs text-gray-600">
+ Instantly save any webpage to your memory.
+ </p>
+ </div>
+ </div>
+
+ <div className="flex items-start gap-3">
+ <div className="w-10 h-10 bg-green-50 border border-green-200 rounded-lg flex items-center justify-center flex-shrink-0">
+ <Zap className="w-5 h-5 text-green-600" />
+ </div>
+ <div>
+ <h3 className="font-semibold text-sm text-gray-800">
+ Charge Empty Memory
+ </h3>
+ <p className="text-xs text-gray-600">
+ Automatically capture & organize your browsing history.
+ </p>
+ </div>
+ </div>
+ </div>
+
+ <div className="px-6 pb-4">
+ <Button
+ onClick={handleInstall}
+ className="w-full bg-white border border-[#686CFD] text-gray-800 hover:bg-gray-50 font-semibold rounded-lg h-10 flex items-center justify-center gap-3"
+ >
+ <div className="w-6 h-6 bg-[#686CFD] rounded-full flex items-center justify-center">
+ <Image
+ src="/images/extension-logo.png"
+ alt="Extension Logo"
+ width={24}
+ height={24}
+ />
+ </div>
+ Add to Chrome - It's Free
+ </Button>
+ </div>
+
+ <div className="px-6 pb-4 flex items-center justify-center gap-6 text-xs text-gray-500">
+ <div className="flex items-center gap-1">
+ <Users className="w-3 h-3" />
+ <span>4K+ users</span>
+ </div>
+ <div className="flex items-center gap-1">
+ <Lock className="w-3 h-3" />
+ <span>Privacy first</span>
+ </div>
+ </div>
+ </motion.div>
+ )}
+
+ {isMinimized && (
+ <div className="relative flex items-center w-full group">
+ <Button
+ size={"lg"}
+ onClick={handleInstall}
+ className="text-xs rounded-full"
+ style={{
+ backgroundImage: "url('/images/extension-bg.png')",
+ backgroundSize: "cover",
+ backgroundPosition: "center",
+ backgroundRepeat: "no-repeat",
+ }}
+ >
+ <ChromeIcon className="h-3 w-3 mr-1" />
+ Get Extension
+ </Button>
+ <Button
+ variant="ghost"
+ size="sm"
+ onClick={handleDismiss}
+ className="absolute top-[-16px] right-[-12px] h-6 w-6 p-0 text-muted-foreground hover:text-foreground opacity-0 group-hover:opacity-75 transition-opacity duration-200"
+ >
+ <CircleX className="w-4 h-4" />
+ </Button>
+ </div>
+ )}
+ </div>
+ </motion.div>
+ )
+}
diff --git a/apps/web/components/content-cards/google-docs.tsx b/apps/web/components/content-cards/google-docs.tsx
index 22f06f77..0306876d 100644
--- a/apps/web/components/content-cards/google-docs.tsx
+++ b/apps/web/components/content-cards/google-docs.tsx
@@ -2,8 +2,18 @@
import { Card, CardContent } from "@repo/ui/components/card"
import { Badge } from "@repo/ui/components/badge"
-import { ExternalLink, FileText, Brain } from "lucide-react"
-import { useState } from "react"
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+ AlertDialogTrigger,
+} from "@repo/ui/components/alert-dialog"
+import { ExternalLink, FileText, Brain, Trash2 } from "lucide-react"
import { cn } from "@lib/utils"
import { colors } from "@repo/ui/memory-graph/constants"
import { getPastelBackgroundColor } from "../memories-utils"
@@ -14,6 +24,7 @@ interface GoogleDocsCardProps {
description?: string | null
className?: string
onClick?: () => void
+ onDelete?: () => void
showExternalLink?: boolean
activeMemories?: Array<{ id: string; isForgotten?: boolean }>
lastModified?: string | Date
@@ -25,12 +36,11 @@ export const GoogleDocsCard = ({
description,
className,
onClick,
+ onDelete,
showExternalLink = true,
activeMemories,
lastModified,
}: GoogleDocsCardProps) => {
- const [imageError, setImageError] = useState(false)
-
const handleCardClick = () => {
if (onClick) {
onClick()
@@ -57,6 +67,54 @@ export const GoogleDocsCard = ({
backgroundColor: getPastelBackgroundColor(url || title || "googledocs"),
}}
>
+ {onDelete && (
+ <AlertDialog>
+ <AlertDialogTrigger asChild>
+ <button
+ className="absolute top-2 right-2 z-20 opacity-0 group-hover:opacity-100 transition-opacity p-1.5 rounded-md hover:bg-red-500/20"
+ onClick={(e) => {
+ e.stopPropagation()
+ }}
+ style={{
+ color: colors.text.muted,
+ backgroundColor: "rgba(255, 255, 255, 0.1)",
+ backdropFilter: "blur(4px)",
+ }}
+ type="button"
+ >
+ <Trash2 className="w-3.5 h-3.5" />
+ </button>
+ </AlertDialogTrigger>
+ <AlertDialogContent>
+ <AlertDialogHeader>
+ <AlertDialogTitle>Delete Document</AlertDialogTitle>
+ <AlertDialogDescription>
+ Are you sure you want to delete this document and all its
+ related memories? This action cannot be undone.
+ </AlertDialogDescription>
+ </AlertDialogHeader>
+ <AlertDialogFooter>
+ <AlertDialogCancel
+ onClick={(e) => {
+ e.stopPropagation()
+ }}
+ >
+ Cancel
+ </AlertDialogCancel>
+ <AlertDialogAction
+ className="bg-red-600 hover:bg-red-700 text-white"
+ onClick={(e) => {
+ e.stopPropagation()
+ onDelete()
+ }}
+ >
+ Delete
+ </AlertDialogAction>
+ </AlertDialogFooter>
+ </AlertDialogContent>
+ </AlertDialog>
+ )}
+
<CardContent className="p-0">
<div className="px-4 border-b border-white/10">
<div className="flex items-center justify-between">
@@ -99,16 +157,18 @@ export const GoogleDocsCard = ({
</span>
</div>
</div>
- {showExternalLink && (
- <button
- onClick={handleExternalLinkClick}
- className="opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded hover:bg-white/10 flex-shrink-0"
- type="button"
- aria-label="Open in Google Docs"
- >
- <ExternalLink className="w-4 h-4" />
- </button>
- )}
+ <div className="flex items-center gap-1">
+ {showExternalLink && (
+ <button
+ onClick={handleExternalLinkClick}
+ className="opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded hover:bg-white/10 flex-shrink-0"
+ type="button"
+ aria-label="Open in Google Docs"
+ >
+ <ExternalLink className="w-4 h-4" />
+ </button>
+ )}
+ </div>
</div>
</div>
diff --git a/apps/web/components/content-cards/note.tsx b/apps/web/components/content-cards/note.tsx
index e7703d9b..b0014bf6 100644
--- a/apps/web/components/content-cards/note.tsx
+++ b/apps/web/components/content-cards/note.tsx
@@ -1,8 +1,19 @@
import { Badge } from "@repo/ui/components/badge"
import { Card, CardContent, CardHeader } from "@repo/ui/components/card"
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+ AlertDialogTrigger,
+} from "@repo/ui/components/alert-dialog"
import { colors } from "@repo/ui/memory-graph/constants"
-import { Brain, ExternalLink } from "lucide-react"
+import { Brain, ExternalLink, Trash2 } from "lucide-react"
import { cn } from "@lib/utils"
import {
formatDate,
@@ -32,6 +43,7 @@ export const NoteCard = ({
activeMemories,
forgottenMemories,
onOpenDetails,
+ onDelete,
}: NoteCardProps) => {
return (
<Card
@@ -47,6 +59,52 @@ export const NoteCard = ({
width: width,
}}
>
+ <AlertDialog>
+ <AlertDialogTrigger asChild>
+ <button
+ className="absolute top-2 right-2 z-20 opacity-0 group-hover:opacity-100 group-hover:cursor-pointer transition-opacity p-1.5 rounded-md hover:bg-red-500/20"
+ onClick={(e) => {
+ e.stopPropagation()
+ }}
+ style={{
+ color: colors.text.muted,
+ backgroundColor: "rgba(255, 255, 255, 0.1)",
+ backdropFilter: "blur(4px)",
+ }}
+ type="button"
+ >
+ <Trash2 className="w-3.5 h-3.5" />
+ </button>
+ </AlertDialogTrigger>
+ <AlertDialogContent>
+ <AlertDialogHeader>
+ <AlertDialogTitle>Delete Document</AlertDialogTitle>
+ <AlertDialogDescription>
+ Are you sure you want to delete this document and all its related
+ memories? This action cannot be undone.
+ </AlertDialogDescription>
+ </AlertDialogHeader>
+ <AlertDialogFooter>
+ <AlertDialogCancel
+ onClick={(e) => {
+ e.stopPropagation()
+ }}
+ >
+ Cancel
+ </AlertDialogCancel>
+ <AlertDialogAction
+ className="bg-red-600 hover:bg-red-700 text-white"
+ onClick={(e) => {
+ e.stopPropagation()
+ onDelete(document)
+ }}
+ >
+ Delete
+ </AlertDialogAction>
+ </AlertDialogFooter>
+ </AlertDialogContent>
+ </AlertDialog>
+
<CardHeader className="relative z-10 px-0 pb-0">
<div className="flex items-center justify-between gap-2">
<div className="flex items-center gap-1">
@@ -59,23 +117,25 @@ export const NoteCard = ({
{document.title || "Untitled Document"}
</p>
</div>
- {document.url && (
- <button
- className="opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded"
- onClick={(e) => {
- e.stopPropagation()
- const sourceUrl = getSourceUrl(document)
- window.open(sourceUrl ?? undefined, "_blank")
- }}
- style={{
- backgroundColor: "rgba(255, 255, 255, 0.05)",
- color: colors.text.secondary,
- }}
- type="button"
- >
- <ExternalLink className="w-3 h-3" />
- </button>
- )}
+ <div className="flex items-center gap-1">
+ {document.url && (
+ <button
+ className="opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded"
+ onClick={(e) => {
+ e.stopPropagation()
+ const sourceUrl = getSourceUrl(document)
+ window.open(sourceUrl ?? undefined, "_blank")
+ }}
+ style={{
+ backgroundColor: "rgba(255, 255, 255, 0.05)",
+ color: colors.text.secondary,
+ }}
+ type="button"
+ >
+ <ExternalLink className="w-3 h-3" />
+ </button>
+ )}
+ </div>
<div className="flex items-center gap-2 text-[10px] text-muted-foreground">
<span>{formatDate(document.createdAt)}</span>
</div>
diff --git a/apps/web/components/content-cards/tweet.tsx b/apps/web/components/content-cards/tweet.tsx
index 3f46d6cc..34db9eb5 100644
--- a/apps/web/components/content-cards/tweet.tsx
+++ b/apps/web/components/content-cards/tweet.tsx
@@ -14,7 +14,18 @@ import {
enrichTweet,
} from "react-tweet"
import { Badge } from "@repo/ui/components/badge"
-import { Brain } from "lucide-react"
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+ AlertDialogTrigger,
+} from "@repo/ui/components/alert-dialog"
+import { Brain, Trash2 } from "lucide-react"
import { colors } from "@repo/ui/memory-graph/constants"
import { getPastelBackgroundColor } from "../memories-utils"
@@ -71,18 +82,69 @@ const CustomTweet = ({
export const TweetCard = ({
data,
activeMemories,
+ onDelete,
}: {
data: Tweet
activeMemories?: Array<{ id: string; isForgotten?: boolean }>
+ onDelete?: () => void
}) => {
return (
<div
- className="relative transition-all"
+ className="relative transition-all group"
style={{
backgroundColor: getPastelBackgroundColor(data.id_str || "tweet"),
}}
>
<CustomTweet components={{}} tweet={data} />
+
+ {onDelete && (
+ <AlertDialog>
+ <AlertDialogTrigger asChild>
+ <button
+ className="absolute top-2 right-2 z-20 opacity-0 group-hover:opacity-100 transition-opacity p-1.5 rounded-md hover:bg-red-500/20"
+ onClick={(e) => {
+ e.stopPropagation()
+ }}
+ style={{
+ color: colors.text.muted,
+ backgroundColor: "rgba(255, 255, 255, 0.1)",
+ backdropFilter: "blur(4px)",
+ }}
+ type="button"
+ >
+ <Trash2 className="w-3.5 h-3.5" />
+ </button>
+ </AlertDialogTrigger>
+ <AlertDialogContent>
+ <AlertDialogHeader>
+ <AlertDialogTitle>Delete Document</AlertDialogTitle>
+ <AlertDialogDescription>
+ Are you sure you want to delete this document and all its
+ related memories? This action cannot be undone.
+ </AlertDialogDescription>
+ </AlertDialogHeader>
+ <AlertDialogFooter>
+ <AlertDialogCancel
+ onClick={(e) => {
+ e.stopPropagation()
+ }}
+ >
+ Cancel
+ </AlertDialogCancel>
+ <AlertDialogAction
+ className="bg-red-600 hover:bg-red-700 text-white"
+ onClick={(e) => {
+ e.stopPropagation()
+ onDelete()
+ }}
+ >
+ Delete
+ </AlertDialogAction>
+ </AlertDialogFooter>
+ </AlertDialogContent>
+ </AlertDialog>
+ )}
+
{activeMemories && activeMemories.length > 0 && (
<div className="absolute bottom-2 left-4 z-10">
<Badge
diff --git a/apps/web/components/content-cards/website.tsx b/apps/web/components/content-cards/website.tsx
index f36cd247..b3ee7df6 100644
--- a/apps/web/components/content-cards/website.tsx
+++ b/apps/web/components/content-cards/website.tsx
@@ -1,10 +1,22 @@
"use client"
import { Card, CardContent } from "@repo/ui/components/card"
-import { ExternalLink } from "lucide-react"
+import {
+ AlertDialog,
+ AlertDialogAction,
+ AlertDialogCancel,
+ AlertDialogContent,
+ AlertDialogDescription,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogTitle,
+ AlertDialogTrigger,
+} from "@repo/ui/components/alert-dialog"
+import { ExternalLink, Trash2 } from "lucide-react"
import { useState } from "react"
import { cn } from "@lib/utils"
import { getPastelBackgroundColor } from "../memories-utils"
+import { colors } from "@repo/ui/memory-graph/constants"
interface WebsiteCardProps {
title: string
@@ -13,6 +25,7 @@ interface WebsiteCardProps {
description?: string
className?: string
onClick?: () => void
+ onDelete?: () => void
showExternalLink?: boolean
}
@@ -23,6 +36,7 @@ export const WebsiteCard = ({
description,
className,
onClick,
+ onDelete,
showExternalLink = true,
}: WebsiteCardProps) => {
const [imageError, setImageError] = useState(false)
@@ -51,7 +65,7 @@ export const WebsiteCard = ({
return (
<Card
className={cn(
- "cursor-pointer transition-all hover:shadow-md group overflow-hidden py-0",
+ "cursor-pointer transition-all hover:shadow-md group overflow-hidden py-0 relative",
className,
)}
onClick={handleCardClick}
@@ -59,6 +73,54 @@ export const WebsiteCard = ({
backgroundColor: getPastelBackgroundColor(url || title || "website"),
}}
>
+ {onDelete && (
+ <AlertDialog>
+ <AlertDialogTrigger asChild>
+ <button
+ className="absolute top-2 right-2 z-20 opacity-0 group-hover:opacity-100 transition-opacity p-1.5 rounded-md hover:bg-red-500/20"
+ onClick={(e) => {
+ e.stopPropagation()
+ }}
+ style={{
+ color: colors.text.muted,
+ backgroundColor: "rgba(255, 255, 255, 0.1)",
+ backdropFilter: "blur(4px)",
+ }}
+ type="button"
+ >
+ <Trash2 className="w-3.5 h-3.5" />
+ </button>
+ </AlertDialogTrigger>
+ <AlertDialogContent>
+ <AlertDialogHeader>
+ <AlertDialogTitle>Delete Document</AlertDialogTitle>
+ <AlertDialogDescription>
+ Are you sure you want to delete this document and all its
+ related memories? This action cannot be undone.
+ </AlertDialogDescription>
+ </AlertDialogHeader>
+ <AlertDialogFooter>
+ <AlertDialogCancel
+ onClick={(e) => {
+ e.stopPropagation()
+ }}
+ >
+ Cancel
+ </AlertDialogCancel>
+ <AlertDialogAction
+ className="bg-red-600 hover:bg-red-700 text-white"
+ onClick={(e) => {
+ e.stopPropagation()
+ onDelete()
+ }}
+ >
+ Delete
+ </AlertDialogAction>
+ </AlertDialogFooter>
+ </AlertDialogContent>
+ </AlertDialog>
+ )}
+
<CardContent className="p-0">
{image && !imageError && (
<div className="relative h-38 bg-gray-100 overflow-hidden">
@@ -75,16 +137,18 @@ export const WebsiteCard = ({
<div className="px-4 py-2 space-y-2">
<div className="font-semibold text-sm line-clamp-2 leading-tight flex items-center justify-between">
{title}
- {showExternalLink && (
- <button
- onClick={handleExternalLinkClick}
- className="opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded hover:bg-gray-100 flex-shrink-0"
- type="button"
- aria-label="Open in new tab"
- >
- <ExternalLink className="w-3 h-3" />
- </button>
- )}
+ <div className="flex items-center gap-1">
+ {showExternalLink && (
+ <button
+ onClick={handleExternalLinkClick}
+ className="opacity-0 group-hover:opacity-100 transition-opacity p-1 rounded hover:bg-gray-100 flex-shrink-0"
+ type="button"
+ aria-label="Open in new tab"
+ >
+ <ExternalLink className="w-3 h-3" />
+ </button>
+ )}
+ </div>
</div>
{description && (
diff --git a/apps/web/components/header.tsx b/apps/web/components/header.tsx
index b51b4b84..c055e94d 100644
--- a/apps/web/components/header.tsx
+++ b/apps/web/components/header.tsx
@@ -1,7 +1,17 @@
import { Button } from "@ui/components/button"
import { Logo, LogoFull } from "@ui/assets/Logo"
import Link from "next/link"
-import { MoonIcon, Plus, SunIcon, MonitorIcon, Network } from "lucide-react"
+import {
+ MoonIcon,
+ Plus,
+ SunIcon,
+ MonitorIcon,
+ Network,
+ User,
+ CreditCard,
+ Chrome,
+ LogOut,
+} from "lucide-react"
import {
DropdownMenuContent,
DropdownMenuTrigger,
@@ -93,14 +103,28 @@ export function Header({ onAddMemory }: { onAddMemory?: () => void }) {
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => router.push("/settings")}>
+ <User className="h-4 w-4 mr-2" />
Profile
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => router.push("/settings/billing")}
>
+ <CreditCard className="h-4 w-4 mr-2" />
Billing
</DropdownMenuItem>
<DropdownMenuItem
+ onClick={() => {
+ window.open(
+ "https://chromewebstore.google.com/detail/supermemory/afpgkkipfdpeaflnpoaffkcankadgjfc",
+ "_blank",
+ "noopener,noreferrer",
+ )
+ }}
+ >
+ <Chrome className="h-4 w-4 mr-2" />
+ Chrome Extension
+ </DropdownMenuItem>
+ <DropdownMenuItem
className="flex items-center justify-between p-2 cursor-default hover:bg-transparent focus:bg-transparent data-[highlighted]:bg-transparent"
onSelect={(e) => e.preventDefault()}
>
@@ -164,6 +188,7 @@ export function Header({ onAddMemory }: { onAddMemory?: () => void }) {
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem onClick={() => handleSignOut()}>
+ <LogOut className="h-4 w-4 mr-2" />
Logout
</DropdownMenuItem>
</DropdownMenuContent>
diff --git a/apps/web/components/masonry-memory-list.tsx b/apps/web/components/masonry-memory-list.tsx
index 2f634f74..93326e49 100644
--- a/apps/web/components/masonry-memory-list.tsx
+++ b/apps/web/components/masonry-memory-list.tsx
@@ -63,6 +63,7 @@ const DocumentCard = memo(
description={document.content}
activeMemories={activeMemories}
lastModified={document.updatedAt || document.createdAt}
+ onDelete={() => onDelete(document)}
/>
)
}
@@ -77,6 +78,7 @@ const DocumentCard = memo(
document.metadata?.sm_internal_twitter_metadata as unknown as Tweet
}
activeMemories={activeMemories}
+ onDelete={() => onDelete(document)}
/>
)
}
@@ -87,6 +89,7 @@ const DocumentCard = memo(
url={document.url}
title={document.title || "Untitled Document"}
image={document.ogImage}
+ onDelete={() => onDelete(document)}
/>
)
}
@@ -212,9 +215,7 @@ export const MasonryMemoryList = ({
) : isLoading ? (
<div className="h-full flex items-center justify-center p-4">
<div className="rounded-xl overflow-hidden">
- <div
- className="relative z-10 px-6 py-4"
- >
+ <div className="relative z-10 px-6 py-4">
<div className="flex items-center gap-2">
<Sparkles className="w-4 h-4 animate-spin text-blue-400" />
<span>Loading memory list...</span>
@@ -232,6 +233,7 @@ export const MasonryMemoryList = ({
data-theme="light"
>
<Masonry
+ key={`masonry-${filteredDocuments.length}-${filteredDocuments.map((d) => d.id).join(",")}`}
items={filteredDocuments}
render={renderDocumentCard}
columnGutter={16}
diff --git a/apps/web/components/views/add-memory/action-buttons.tsx b/apps/web/components/views/add-memory/action-buttons.tsx
index fc901ba9..3f93fe17 100644
--- a/apps/web/components/views/add-memory/action-buttons.tsx
+++ b/apps/web/components/views/add-memory/action-buttons.tsx
@@ -1,67 +1,67 @@
-import { Button } from '@repo/ui/components/button';
-import { Loader2, type LucideIcon } from 'lucide-react';
-import { motion } from 'motion/react';
+import { Button } from "@repo/ui/components/button"
+import { Loader2, type LucideIcon } from "lucide-react"
+import { motion } from "motion/react"
interface ActionButtonsProps {
- onCancel: () => void;
- onSubmit?: () => void;
- submitText: string;
- submitIcon?: LucideIcon;
- isSubmitting?: boolean;
- isSubmitDisabled?: boolean;
- submitType?: 'button' | 'submit';
- className?: string;
+ onCancel: () => void
+ onSubmit?: () => void
+ submitText: string
+ submitIcon?: LucideIcon
+ isSubmitting?: boolean
+ isSubmitDisabled?: boolean
+ submitType?: "button" | "submit"
+ className?: string
}
export function ActionButtons({
- onCancel,
- onSubmit,
- submitText,
- submitIcon: SubmitIcon,
- isSubmitting = false,
- isSubmitDisabled = false,
- submitType = 'submit',
- className = '',
+ onCancel,
+ onSubmit,
+ submitText,
+ submitIcon: SubmitIcon,
+ isSubmitting = false,
+ isSubmitDisabled = false,
+ submitType = "submit",
+ className = "",
}: ActionButtonsProps) {
- return (
- <div className={`flex gap-3 order-1 sm:order-2 justify-end ${className}`}>
- <Button
- className="hover:bg-foreground/10 border-none flex-1 sm:flex-initial"
- onClick={onCancel}
- type="button"
- variant="ghost"
- >
- Cancel
- </Button>
+ return (
+ <div className={`flex gap-3 order-1 sm:order-2 justify-end ${className}`}>
+ <Button
+ className="hover:bg-foreground/10 border-none flex-1 sm:flex-initial"
+ onClick={onCancel}
+ type="button"
+ variant="ghost"
+ >
+ Cancel
+ </Button>
- <motion.div
- whileHover={{ scale: 1.05 }}
- whileTap={{ scale: 0.95 }}
- className="flex-1 sm:flex-initial"
- >
- <Button
- className="bg-foreground hover:bg-foreground/20 border-foreground/20 w-full"
- disabled={isSubmitting || isSubmitDisabled}
- onClick={submitType === 'button' ? onSubmit : undefined}
- type={submitType}
- >
- {isSubmitting ? (
- <>
- <Loader2 className="h-4 w-4 animate-spin mr-2" />
- {submitText.includes('Add')
- ? 'Adding...'
- : submitText.includes('Upload')
- ? 'Uploading...'
- : 'Processing...'}
- </>
- ) : (
- <>
- {SubmitIcon && <SubmitIcon className="h-4 w-4 mr-2" />}
- {submitText}
- </>
- )}
- </Button>
- </motion.div>
- </div>
- );
+ <motion.div
+ whileHover={{ scale: 1.05 }}
+ whileTap={{ scale: 0.95 }}
+ className="flex-1 sm:flex-initial"
+ >
+ <Button
+ className="w-full"
+ disabled={isSubmitting || isSubmitDisabled}
+ onClick={submitType === "button" ? onSubmit : undefined}
+ type={submitType}
+ >
+ {isSubmitting ? (
+ <>
+ <Loader2 className="h-4 w-4 animate-spin mr-2" />
+ {submitText.includes("Add")
+ ? "Adding..."
+ : submitText.includes("Upload")
+ ? "Uploading..."
+ : "Processing..."}
+ </>
+ ) : (
+ <>
+ {SubmitIcon && <SubmitIcon className="h-4 w-4 mr-2" />}
+ {submitText}
+ </>
+ )}
+ </Button>
+ </motion.div>
+ </div>
+ )
}
diff --git a/apps/web/components/views/add-memory/index.tsx b/apps/web/components/views/add-memory/index.tsx
index a78e7629..d9c6aef8 100644
--- a/apps/web/components/views/add-memory/index.tsx
+++ b/apps/web/components/views/add-memory/index.tsx
@@ -88,7 +88,10 @@ export function AddMemoryView({
const [newProjectName, setNewProjectName] = useState("")
// Check memory limits
- const { data: memoriesCheck } = fetchMemoriesFeature(autumn, !autumn.isLoading)
+ const { data: memoriesCheck } = fetchMemoriesFeature(
+ autumn,
+ !autumn.isLoading,
+ )
const memoriesUsed = memoriesCheck?.usage ?? 0
const memoriesLimit = memoriesCheck?.included_usage ?? 0
@@ -757,7 +760,7 @@ export function AddMemoryView({
{({ state, handleChange, handleBlur }) => (
<>
<Input
- className={`bg-black/5 border-black/10 text-black ${
+ className={`bg-black/5 border-black/10 ${
addContentMutation.isPending ? "opacity-50" : ""
}`}
disabled={addContentMutation.isPending}
diff --git a/apps/web/components/views/billing.tsx b/apps/web/components/views/billing.tsx
index 679b648e..25e28374 100644
--- a/apps/web/components/views/billing.tsx
+++ b/apps/web/components/views/billing.tsx
@@ -118,17 +118,9 @@ export function BillingView() {
<div className="flex justify-between items-center">
<span className="text-sm text-muted-foreground">Memories</span>
<span className="text-sm text-foreground">
- {memoriesUsed} / {memoriesLimit}
+ Unlimited
</span>
</div>
- <div className="w-full bg-muted-foreground/50 rounded-full h-2">
- <div
- className="bg-green-500 h-2 rounded-full transition-all"
- style={{
- width: `${Math.min((memoriesUsed / memoriesLimit) * 100, 100)}%`,
- }}
- />
- </div>
</div>
<div className="space-y-2">
<div className="flex justify-between items-center">
diff --git a/apps/web/components/views/integrations.tsx b/apps/web/components/views/integrations.tsx
index dadd7dc6..5a6d09d0 100644
--- a/apps/web/components/views/integrations.tsx
+++ b/apps/web/components/views/integrations.tsx
@@ -4,6 +4,7 @@ import { useAuth } from "@lib/auth-context"
import { generateId } from "@lib/generate-id"
import {
ADD_MEMORY_SHORTCUT_URL,
+ RAYCAST_EXTENSION_URL,
SEARCH_MEMORY_SHORTCUT_URL,
} from "@repo/lib/constants"
import { fetchConnectionsFeature } from "@repo/lib/queries"
@@ -20,9 +21,17 @@ 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 { Check, Copy, Smartphone, Trash2 } from "lucide-react"
+import {
+ Check,
+ Copy,
+ DownloadIcon,
+ KeyIcon,
+ Smartphone,
+ Trash2,
+} from "lucide-react"
import { motion } from "motion/react"
import Image from "next/image"
+import { useSearchParams } from "next/navigation"
import { useEffect, useId, useState } from "react"
import { toast } from "sonner"
import type { z } from "zod"
@@ -87,6 +96,7 @@ export function IntegrationsView() {
const queryClient = useQueryClient()
const { selectedProject } = useProject()
const autumn = useCustomer()
+ const searchParams = useSearchParams()
const [showApiKeyModal, setShowApiKeyModal] = useState(false)
const [apiKey, setApiKey] = useState<string>("")
const [copied, setCopied] = useState(false)
@@ -94,7 +104,12 @@ export function IntegrationsView() {
const [selectedShortcutType, setSelectedShortcutType] = useState<
"add" | "search" | null
>(null)
+ const [showRaycastApiKeyModal, setShowRaycastApiKeyModal] = useState(false)
+ const [raycastApiKey, setRaycastApiKey] = useState<string>("")
+ const [raycastCopied, setRaycastCopied] = useState(false)
+ const [hasTriggeredRaycast, setHasTriggeredRaycast] = useState(false)
const apiKeyId = useId()
+ const raycastApiKeyId = useId()
const handleUpgrade = async () => {
try {
@@ -233,7 +248,7 @@ export function IntegrationsView() {
setApiKey(apiKey)
setShowApiKeyModal(true)
setCopied(false)
- handleCopyApiKey()
+ handleCopyApiKey(apiKey)
},
onError: (error) => {
toast.error("Failed to create API key", {
@@ -242,12 +257,54 @@ export function IntegrationsView() {
},
})
+ const createRaycastApiKeyMutation = useMutation({
+ mutationFn: async () => {
+ if (!org?.id) {
+ throw new Error("Organization ID is required")
+ }
+
+ const res = await authClient.apiKey.create({
+ metadata: {
+ organizationId: org?.id,
+ type: "raycast-extension",
+ },
+ name: `raycast-${generateId().slice(0, 8)}`,
+ prefix: `sm_${org?.id}_`,
+ })
+ return res.key
+ },
+ onSuccess: (apiKey) => {
+ setRaycastApiKey(apiKey)
+ setShowRaycastApiKeyModal(true)
+ setRaycastCopied(false)
+ handleCopyApiKey(apiKey)
+ },
+ onError: (error) => {
+ toast.error("Failed to create Raycast API key", {
+ description: error instanceof Error ? error.message : "Unknown error",
+ })
+ },
+ })
+
+ useEffect(() => {
+ const qParam = searchParams.get("q")
+ if (
+ qParam === "raycast" &&
+ !hasTriggeredRaycast &&
+ !createRaycastApiKeyMutation.isPending &&
+ org?.id
+ ) {
+ setHasTriggeredRaycast(true)
+ createRaycastApiKeyMutation.mutate()
+ }
+ }, [searchParams, hasTriggeredRaycast, createRaycastApiKeyMutation, org])
+
const handleShortcutClick = (shortcutType: "add" | "search") => {
setSelectedShortcutType(shortcutType)
createApiKeyMutation.mutate()
}
- const handleCopyApiKey = async () => {
+ const handleCopyApiKey = async (apiKey: string) => {
try {
await navigator.clipboard.writeText(apiKey)
setCopied(true)
@@ -281,6 +338,18 @@ export function IntegrationsView() {
}
}
+ const handleRaycastDialogClose = (open: boolean) => {
+ setShowRaycastApiKeyModal(open)
+ if (!open) {
+ setRaycastApiKey("")
+ setRaycastCopied(false)
+ }
+ }
+
+ const handleRaycastClick = () => {
+ createRaycastApiKeyMutation.mutate()
+ }
+
return (
<div className="space-y-4 sm:space-y-4 custom-scrollbar">
{/* iOS Shortcuts */}
@@ -336,6 +405,64 @@ export function IntegrationsView() {
</div>
</div>
+ {/* Raycast Extension */}
+ <div className="bg-card rounded-xl border border-border overflow-hidden shadow-sm">
+ <div className="p-4 sm:p-5">
+ <div className="flex items-start gap-3 mb-3">
+ <div className="p-2 bg-purple-500/10 rounded-lg flex-shrink-0">
+ <svg
+ width="24"
+ height="24"
+ viewBox="0 0 28 28"
+ fill="none"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <title>Raycast Icon</title>
+ <path
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ d="M7 18.079V21L0 14L1.46 12.54L7 18.081V18.079ZM9.921 21H7L14 28L15.46 26.54L9.921 21ZM26.535 15.462L27.996 14L13.996 0L12.538 1.466L18.077 7.004H14.73L10.864 3.146L9.404 4.606L11.809 7.01H10.129V17.876H20.994V16.196L23.399 18.6L24.859 17.14L20.994 13.274V9.927L26.535 15.462ZM7.73 6.276L6.265 7.738L7.833 9.304L9.294 7.844L7.73 6.276ZM20.162 18.708L18.702 20.17L20.268 21.738L21.73 20.276L20.162 18.708ZM4.596 9.41L3.134 10.872L7 14.738V11.815L4.596 9.41ZM16.192 21.006H13.268L17.134 24.872L18.596 23.41L16.192 21.006Z"
+ fill="#FF6363"
+ />
+ </svg>
+ </div>
+ <div className="flex-1 min-w-0">
+ <h3 className="text-card-foreground font-semibold text-base mb-1">
+ Raycast Extension
+ </h3>
+ <p className="text-muted-foreground text-sm leading-relaxed">
+ Add and search memories directly from Raycast on Mac and
+ Windows.
+ </p>
+ </div>
+ </div>
+ <div className="flex flex-col sm:flex-row gap-2 sm:gap-3">
+ <Button
+ variant="secondary"
+ className="flex-1"
+ onClick={handleRaycastClick}
+ disabled={createRaycastApiKeyMutation.isPending}
+ >
+ <KeyIcon className="h-4 w-4" />
+ {createRaycastApiKeyMutation.isPending
+ ? "Generating..."
+ : "Get API Key"}
+ </Button>
+ <Button
+ variant="secondary"
+ className="flex-1"
+ onClick={() => {
+ window.open(RAYCAST_EXTENSION_URL, "_blank")
+ analytics.extensionInstallClicked()
+ }}
+ >
+ <DownloadIcon className="h-4 w-4" />
+ Install Extension
+ </Button>
+ </div>
+ </div>
+ </div>
+
{/* Chrome Extension */}
<div className="bg-card rounded-xl border border-border overflow-hidden shadow-sm">
<div className="p-4 sm:p-5">
@@ -630,8 +757,8 @@ export function IntegrationsView() {
<Button
size="sm"
variant="ghost"
- onClick={handleCopyApiKey}
- className="hover:bg-accent"
+ onClick={() => handleCopyApiKey(apiKey)}
+ className="text-white/70 hover:text-white hover:bg-white/10"
>
{copied ? (
<Check className="h-4 w-4 text-chart-2" />
@@ -696,6 +823,115 @@ export function IntegrationsView() {
</DialogContent>
</DialogPortal>
</Dialog>
+
+ <Dialog
+ open={showRaycastApiKeyModal}
+ onOpenChange={handleRaycastDialogClose}
+ >
+ <DialogPortal>
+ <DialogContent className="bg-card border-border text-card-foreground md:max-w-md z-[100]">
+ <DialogHeader>
+ <DialogTitle className="text-card-foreground text-lg font-semibold">
+ Setup Raycast Extension
+ </DialogTitle>
+ </DialogHeader>
+
+ <div className="space-y-4">
+ {/* API Key Section */}
+ <div className="space-y-2">
+ <label
+ htmlFor={raycastApiKeyId}
+ className="text-sm font-medium text-muted-foreground"
+ >
+ Your Raycast API Key
+ </label>
+ <div className="flex items-center gap-2">
+ <input
+ id={raycastApiKeyId}
+ type="text"
+ value={raycastApiKey}
+ readOnly
+ className="flex-1 bg-input border border-border rounded-lg px-3 py-2 text-sm text-foreground font-mono"
+ />
+ <Button
+ size="sm"
+ variant="ghost"
+ onClick={() => handleCopyApiKey(raycastApiKey)}
+ className="text-muted-foreground hover:text-foreground hover:bg-accent"
+ >
+ {raycastCopied ? (
+ <Check className="h-4 w-4 text-chart-2" />
+ ) : (
+ <Copy className="h-4 w-4" />
+ )}
+ </Button>
+ </div>
+ </div>
+
+ {/* Steps */}
+ <div className="space-y-3">
+ <h4 className="text-sm font-medium text-muted-foreground">
+ Follow these steps:
+ </h4>
+ <div className="space-y-2">
+ <div className="flex items-start gap-3">
+ <div className="flex-shrink-0 w-6 h-6 bg-purple-500/20 text-purple-500 rounded-full flex items-center justify-center text-xs font-medium">
+ 1
+ </div>
+ <p className="text-sm text-muted-foreground">
+ Install the Raycast extension from the Raycast Store
+ </p>
+ </div>
+ <div className="flex items-start gap-3">
+ <div className="flex-shrink-0 w-6 h-6 bg-purple-500/20 text-purple-500 rounded-full flex items-center justify-center text-xs font-medium">
+ 2
+ </div>
+ <p className="text-sm text-muted-foreground">
+ Open Raycast preferences and paste your API key
+ </p>
+ </div>
+ <div className="flex items-start gap-3">
+ <div className="flex-shrink-0 w-6 h-6 bg-purple-500/20 text-purple-500 rounded-full flex items-center justify-center text-xs font-medium">
+ 3
+ </div>
+ <p className="text-sm text-muted-foreground">
+ Use "Add Memory" or "Search Memories" commands!
+ </p>
+ </div>
+ </div>
+ </div>
+
+ <div className="flex gap-2 pt-2">
+ <Button
+ onClick={() => {
+ window.open(RAYCAST_EXTENSION_URL, "_blank")
+ analytics.extensionInstallClicked()
+ }}
+ className="flex-1"
+ variant="default"
+ >
+ <svg
+ width="24"
+ height="24"
+ viewBox="0 0 28 28"
+ fill="none"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <title>Raycast Icon</title>
+ <path
+ fill-rule="evenodd"
+ clip-rule="evenodd"
+ d="M7 18.079V21L0 14L1.46 12.54L7 18.081V18.079ZM9.921 21H7L14 28L15.46 26.54L9.921 21ZM26.535 15.462L27.996 14L13.996 0L12.538 1.466L18.077 7.004H14.73L10.864 3.146L9.404 4.606L11.809 7.01H10.129V17.876H20.994V16.196L23.399 18.6L24.859 17.14L20.994 13.274V9.927L26.535 15.462ZM7.73 6.276L6.265 7.738L7.833 9.304L9.294 7.844L7.73 6.276ZM20.162 18.708L18.702 20.17L20.268 21.738L21.73 20.276L20.162 18.708ZM4.596 9.41L3.134 10.872L7 14.738V11.815L4.596 9.41ZM16.192 21.006H13.268L17.134 24.872L18.596 23.41L16.192 21.006Z"
+ fill="#FF6363"
+ />
+ </svg>
+ Install Extension
+ </Button>
+ </div>
+ </div>
+ </DialogContent>
+ </DialogPortal>
+ </Dialog>
</div>
)
}
diff --git a/apps/web/components/views/profile.tsx b/apps/web/components/views/profile.tsx
index 93330da4..5aa21231 100644
--- a/apps/web/components/views/profile.tsx
+++ b/apps/web/components/views/profile.tsx
@@ -37,7 +37,10 @@ export function ProfileView() {
const memoriesUsed = memoriesCheck?.usage ?? 0
const memoriesLimit = memoriesCheck?.included_usage ?? 0
- const { data: connectionsCheck } = fetchConnectionsFeature(autumn, !isCheckingStatus && !autumn.isLoading)
+ const { data: connectionsCheck } = fetchConnectionsFeature(
+ autumn,
+ !isCheckingStatus && !autumn.isLoading,
+ )
const connectionsUsed = connectionsCheck?.usage ?? 0
const handleUpgrade = async () => {
@@ -190,26 +193,32 @@ export function ProfileView() {
<div className="space-y-2">
<div className="flex justify-between items-center">
<span className="text-sm text-muted-foreground">Memories</span>
- <span
- className={`text-sm ${memoriesUsed >= memoriesLimit ? "text-red-500" : "text-foreground"}`}
- >
- {memoriesUsed} / {memoriesLimit}
- </span>
- </div>
- <div className="w-full bg-muted-foreground/50 rounded-full h-2">
- <div
- className={`h-2 rounded-full transition-all ${
- memoriesUsed >= memoriesLimit
- ? "bg-red-500"
- : isPro
- ? "bg-green-500"
- : "bg-blue-500"
- }`}
- style={{
- width: `${Math.min((memoriesUsed / memoriesLimit) * 100, 100)}%`,
- }}
- />
+ {isPro ? (
+ <span className="text-sm text-foreground">Unlimited</span>
+ ) : (
+ <span
+ className={`text-sm ${memoriesUsed >= memoriesLimit ? "text-red-500" : "text-foreground"}`}
+ >
+ {memoriesUsed} / {memoriesLimit}
+ </span>
+ )}
</div>
+ {!isPro && (
+ <div className="w-full bg-muted-foreground/50 rounded-full h-2">
+ <div
+ className={`h-2 rounded-full transition-all ${
+ memoriesUsed >= memoriesLimit
+ ? "bg-red-500"
+ : isPro
+ ? "bg-green-500"
+ : "bg-blue-500"
+ }`}
+ style={{
+ width: `${Math.min((memoriesUsed / memoriesLimit) * 100, 100)}%`,
+ }}
+ />
+ </div>
+ )}
</div>
{isPro && (
@@ -322,4 +331,4 @@ export function ProfileView() {
)}
</div>
)
-} \ No newline at end of file
+}
diff --git a/apps/web/public/icons/chrome-transparent.svg b/apps/web/public/icons/chrome-transparent.svg
new file mode 100644
index 00000000..a4bb01b7
--- /dev/null
+++ b/apps/web/public/icons/chrome-transparent.svg
@@ -0,0 +1,13 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_5502_15741)">
+<path d="M13.44 17.3199C13.12 17.3999 12.64 17.5599 12.04 17.5599C10.96 17.5599 9.92002 17.2799 9.04 16.6799C8.15998 16.0799 7.48002 15.3199 6.99998 14.3599L1.87999 5.3999L1.51999 5.99989C0.519977 7.79992 0 9.7999 0 11.9999C0 14.9999 1.00002 17.6399 2.91999 19.8799C4.84001 22.0799 7.31999 23.4399 10.2 23.8799L10.48 23.9199L14.52 16.9999L13.44 17.3199ZM10.04 22.9999C7.47998 22.5599 5.27997 21.3199 3.51998 19.3199C1.71996 17.2399 0.800005 14.7999 0.800005 11.9999C0.800005 10.1999 1.16 8.51991 1.87999 7.0399L6.19998 14.7199C6.71995 15.7599 7.47998 16.6399 8.51998 17.3199C9.55998 17.9599 10.72 18.3199 11.96 18.3199C12.28 18.3199 12.56 18.2799 12.8 18.2399L10.04 22.9999Z" fill="white"/>
+<path d="M6.59935 10.52C6.87933 9.32003 7.55933 8.32001 8.59934 7.52001C9.55932 6.75999 10.6793 6.39999 11.9993 6.39999H22.6393L22.2793 5.8C21.2793 4.07999 19.8793 2.71998 17.9593 1.60001C16.1593 0.519977 14.1593 0 11.9993 0C10.1593 0 8.35934 0.399979 6.75933 1.19998C5.03932 2.03997 3.55931 3.24 2.51936 4.64L2.35938 4.84001L6.35935 11.4L6.59935 10.52ZM3.31936 4.91998C4.27935 3.67996 5.55935 2.67999 7.11937 1.91997C8.59938 1.15995 10.2394 0.799957 11.9994 0.799957C13.9994 0.799957 15.8793 1.31993 17.5193 2.31995C19.1193 3.23995 20.2793 4.31994 21.1994 5.63997H11.9593C10.4793 5.63997 9.19933 6.03995 8.07936 6.91997C7.15936 7.63996 6.47935 8.47995 6.07937 9.47996L3.31936 4.91998Z" fill="white"/>
+<path d="M23.1175 7.48023L22.9975 7.24023H15.0375L15.7175 7.92024C16.9175 9.12022 17.5575 10.5603 17.5575 12.0002C17.5575 13.1602 17.2375 14.2402 16.5575 15.2003L11.4375 24.0003H12.1175C15.3975 23.9603 18.1975 22.7602 20.5175 20.4402C22.8375 18.1202 23.9975 15.2803 23.9975 12.0002C23.9975 10.8002 23.8375 9.08024 23.1175 7.48023ZM19.9575 19.8802C17.9575 21.8802 15.5975 22.9603 12.8375 23.1602L17.1976 15.6402C17.9576 14.5202 18.3176 13.3202 18.3176 12.0002C18.3176 10.6002 17.8376 9.24022 16.8776 8.04024H22.4776C23.0776 9.44024 23.1976 10.9602 23.1976 12.0002C23.1975 15.0402 22.1175 17.6802 19.9575 19.8802Z" fill="white"/>
+<path d="M7.19531 11.9997C7.19531 14.5997 9.39531 16.7997 11.9953 16.7997C14.5953 16.7997 16.7953 14.5997 16.7953 11.9997C16.7953 9.39971 14.5953 7.19971 11.9953 7.19971C9.39531 7.19971 7.19531 9.39971 7.19531 11.9997ZM11.9953 7.99971C14.1553 7.99971 15.9953 9.83972 15.9953 11.9997C15.9953 14.1597 14.1553 15.9997 11.9953 15.9997C9.83532 15.9997 7.99532 14.1597 7.99532 11.9997C7.99532 9.83972 9.83532 7.99971 11.9953 7.99971Z" fill="white"/>
+</g>
+<defs>
+<clipPath id="clip0_5502_15741">
+<rect width="24" height="24" fill="white"/>
+</clipPath>
+</defs>
+</svg>
diff --git a/apps/web/public/images/extension-bg.png b/apps/web/public/images/extension-bg.png
new file mode 100644
index 00000000..c414d088
--- /dev/null
+++ b/apps/web/public/images/extension-bg.png
Binary files differ
diff --git a/apps/web/public/images/extension-logo.png b/apps/web/public/images/extension-logo.png
new file mode 100644
index 00000000..549d267d
--- /dev/null
+++ b/apps/web/public/images/extension-logo.png
Binary files differ