From a7ccd8aee7e89774a48903234a8cf337bd3bcc63 Mon Sep 17 00:00:00 2001 From: himanshu Date: Tue, 15 Oct 2024 18:04:47 +0530 Subject: [PATCH 01/18] ported, inventory showing up --- gui/components.json | 20 + gui/package-lock.json | 2648 ++++++++++++++++++--- gui/package.json | 20 +- gui/src/App.tsx | 5 + gui/src/components/Layout.tsx | 1 + gui/src/components/ui/button.tsx | 57 + gui/src/components/ui/card.tsx | 76 + gui/src/components/ui/input.tsx | 25 + gui/src/components/ui/switch.tsx | 27 + gui/src/components/ui/tabs.tsx | 53 + gui/src/components/ui/tooltip.tsx | 28 + gui/src/inventory/main.tsx | 10 + gui/src/inventory/pages/InventoryPage.tsx | 344 +++ gui/src/inventory/utilities/vscode.ts | 79 + gui/src/pages/gui.tsx | 8 + gui/src/pages/inventory.tsx | 52 + gui/tailwind.config.cjs | 2 +- gui/tsconfig.json | 5 +- gui/vite.config.ts | 6 + 19 files changed, 3091 insertions(+), 375 deletions(-) create mode 100644 gui/components.json create mode 100644 gui/src/components/ui/button.tsx create mode 100644 gui/src/components/ui/card.tsx create mode 100644 gui/src/components/ui/input.tsx create mode 100644 gui/src/components/ui/switch.tsx create mode 100644 gui/src/components/ui/tabs.tsx create mode 100644 gui/src/components/ui/tooltip.tsx create mode 100644 gui/src/inventory/main.tsx create mode 100644 gui/src/inventory/pages/InventoryPage.tsx create mode 100644 gui/src/inventory/utilities/vscode.ts create mode 100644 gui/src/pages/inventory.tsx diff --git a/gui/components.json b/gui/components.json new file mode 100644 index 0000000000..cd5af28cde --- /dev/null +++ b/gui/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": false, + "tsx": true, + "tailwind": { + "config": "tailwind.config.js", + "css": "src/index.css", + "baseColor": "slate", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + } +} \ No newline at end of file diff --git a/gui/package-lock.json b/gui/package-lock.json index 0006b21982..7d5bde64e6 100644 --- a/gui/package-lock.json +++ b/gui/package-lock.json @@ -10,6 +10,11 @@ "@headlessui/react": "^1.7.17", "@heroicons/react": "^2.0.18", "@monaco-editor/react": "^4.6.0", + "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-switch": "^1.1.1", + "@radix-ui/react-tabs": "^1.1.1", + "@radix-ui/react-tooltip": "^1.1.3", "@reduxjs/toolkit": "^1.9.3", "@tiptap/core": "^2.3.2", "@tiptap/extension-document": "^2.3.2", @@ -25,10 +30,13 @@ "@tiptap/starter-kit": "^2.1.13", "@tiptap/suggestion": "^2.1.13", "@types/vscode-webview": "^1.57.1", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", "core": "file:../core", "dompurify": "^3.0.6", "downshift": "^7.6.0", "lodash": "^4.17.21", + "lucide-react": "^0.452.0", "minisearch": "^6.3.0", "onigasm": "^2.2.5", "posthog-js": "^1.130.1", @@ -56,12 +64,15 @@ "socket.io-client": "^4.7.2", "styled-components": "^5.3.6", "table": "^6.8.1", + "tailwind-merge": "^2.5.3", + "tailwindcss-animate": "^1.0.7", "tippy.js": "^6.3.7", "unist-util-visit": "^5.0.0", "uuid": "^9.0.1", "vscode-webview": "^1.0.1-beta.1" }, "devDependencies": { + "@eslint/js": "^9.11.1", "@swc/cli": "^0.3.14", "@swc/core": "^1.7.2", "@types/lodash": "^4.17.6", @@ -72,11 +83,18 @@ "@types/react-router-dom": "^5.3.3", "@types/react-syntax-highlighter": "^15.5.7", "@types/styled-components": "^5.1.26", + "@types/vscode-webview": "^1.57.5", + "@vitejs/plugin-react": "^4.3.2", "@vitejs/plugin-react-swc": "^3.7.0", "autoprefixer": "^10.4.13", + "eslint": "^9.11.1", + "eslint-plugin-react-hooks": "^5.1.0-rc.0", + "eslint-plugin-react-refresh": "^0.4.12", + "globals": "^15.9.0", "postcss": "^8.4.21", "tailwindcss": "^3.2.7", "typescript": "^4.9.3", + "typescript-eslint": "^8.7.0", "vite": "^4.1.0" }, "engines": { @@ -12904,7 +12922,6 @@ }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -12916,7 +12933,6 @@ "node_modules/@ampproject/remapping": { "version": "2.3.0", "license": "Apache-2.0", - "peer": true, "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" @@ -12926,10 +12942,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", + "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.7", + "@babel/highlight": "^7.25.7", "picocolors": "^1.0.0" }, "engines": { @@ -12937,28 +12955,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.24.7", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.8.tgz", + "integrity": "sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA==", "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.24.7", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.8.tgz", + "integrity": "sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg==", "license": "MIT", - "peer": true, "dependencies": { "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-compilation-targets": "^7.24.7", - "@babel/helper-module-transforms": "^7.24.7", - "@babel/helpers": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/helper-compilation-targets": "^7.25.7", + "@babel/helper-module-transforms": "^7.25.7", + "@babel/helpers": "^7.25.7", + "@babel/parser": "^7.25.8", + "@babel/template": "^7.25.7", + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.8", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -12974,13 +12994,15 @@ } }, "node_modules/@babel/generator": { - "version": "7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", + "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7", + "@babel/types": "^7.25.7", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" @@ -12997,13 +13019,14 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", + "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", "license": "MIT", - "peer": true, "dependencies": { - "@babel/compat-data": "^7.24.7", - "@babel/helper-validator-option": "^7.24.7", - "browserslist": "^4.22.2", + "@babel/compat-data": "^7.25.7", + "@babel/helper-validator-option": "^7.25.7", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -13011,58 +13034,29 @@ "node": ">=6.9.0" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "license": "MIT", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", + "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", "license": "MIT", "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", + "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", "license": "MIT", - "peer": true, "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" + "@babel/helper-module-imports": "^7.25.7", + "@babel/helper-simple-access": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", + "@babel/traverse": "^7.25.7" }, "engines": { "node": ">=6.9.0" @@ -13072,73 +13066,74 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz", + "integrity": "sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "license": "MIT", - "peer": true, - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", + "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", "license": "MIT", "dependencies": { - "@babel/types": "^7.24.7" + "@babel/traverse": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", + "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", + "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", + "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", + "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", "license": "MIT", - "peer": true, "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", + "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", + "@babel/helper-validator-identifier": "^7.25.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -13148,8 +13143,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.7", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.8.tgz", + "integrity": "sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ==", "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.8" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -13170,6 +13170,38 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/plugin-transform-react-jsx-self": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.7.tgz", + "integrity": "sha512-JD9MUnLbPL0WdVK8AWC7F7tTG2OS6u/AKKnsK+NdRhUiVdnzyR1S3kKQCaRLOiaULvUiqK6Z4JQE635VgtCFeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-react-jsx-source": { + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.7.tgz", + "integrity": "sha512-S/JXG/KrbIY06iyJPKfxr0qRxnhNOdkNXYBl/rmwgDd72cQLH9tEGkDm/yJPGvcSIUoikzfjMios9i+xT/uv9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, "node_modules/@babel/runtime": { "version": "7.24.7", "license": "MIT", @@ -13181,29 +13213,30 @@ } }, "node_modules/@babel/template": { - "version": "7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", + "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" + "@babel/code-frame": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/types": "^7.25.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.24.7", + "version": "7.25.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", + "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.7", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7", + "@babel/code-frame": "^7.25.7", + "@babel/generator": "^7.25.7", + "@babel/parser": "^7.25.7", + "@babel/template": "^7.25.7", + "@babel/types": "^7.25.7", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -13211,12 +13244,23 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/types": { - "version": "7.24.7", + "version": "7.25.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.8.tgz", + "integrity": "sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg==", "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7", + "@babel/helper-string-parser": "^7.25.7", + "@babel/helper-validator-identifier": "^7.25.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -13242,120 +13286,386 @@ "version": "0.7.5", "license": "MIT" }, - "node_modules/@floating-ui/core": { - "version": "1.6.2", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.0" + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@floating-ui/dom": { - "version": "1.6.5", - "license": "MIT", - "dependencies": { - "@floating-ui/core": "^1.0.0", - "@floating-ui/utils": "^0.2.0" + "node_modules/@eslint-community/eslint-utils/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/@floating-ui/utils": { - "version": "0.2.2", - "license": "MIT" - }, - "node_modules/@headlessui/react": { - "version": "1.7.19", + "node_modules/@eslint-community/regexpp": { + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", + "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", + "dev": true, "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", + "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", + "dev": true, + "license": "Apache-2.0", "dependencies": { - "@tanstack/react-virtual": "^3.0.0-beta.60", - "client-only": "^0.0.1" + "@eslint/object-schema": "^2.1.4", + "debug": "^4.3.1", + "minimatch": "^3.1.2" }, "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": "^16 || ^17 || ^18", - "react-dom": "^16 || ^17 || ^18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@heroicons/react": { - "version": "2.1.5", + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "license": "MIT", - "peerDependencies": { - "react": ">= 16" + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", + "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": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=12" + "node": "*" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", + "node_modules/@eslint/core": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.6.0.tgz", + "integrity": "sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", + "node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", "dev": true, "license": "MIT", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "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": ">=12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/eslint" } }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", + "node_modules/@eslint/eslintrc/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": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" + "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": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } + "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/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/@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.12.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.12.0.tgz", + "integrity": "sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", + "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", + "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@floating-ui/core": { + "version": "1.6.2", + "license": "MIT", + "dependencies": { + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/dom": { + "version": "1.6.5", + "license": "MIT", + "dependencies": { + "@floating-ui/core": "^1.0.0", + "@floating-ui/utils": "^0.2.0" + } + }, + "node_modules/@floating-ui/react-dom": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz", + "integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==", + "license": "MIT", + "dependencies": { + "@floating-ui/dom": "^1.0.0" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@floating-ui/utils": { + "version": "0.2.2", + "license": "MIT" + }, + "node_modules/@headlessui/react": { + "version": "1.7.19", + "license": "MIT", + "dependencies": { + "@tanstack/react-virtual": "^3.0.0-beta.60", + "client-only": "^0.0.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16 || ^17 || ^18", + "react-dom": "^16 || ^17 || ^18" + } + }, + "node_modules/@heroicons/react": { + "version": "2.1.5", + "license": "MIT", + "peerDependencies": { + "react": ">= 16" + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.0.tgz", + "integrity": "sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.5", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.5.tgz", + "integrity": "sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.0", + "@humanwhocodes/retry": "^0.3.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.3.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", + "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.5", + "license": "MIT", + "dependencies": { + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } }, "node_modules/@jridgewell/resolve-uri": { "version": "3.1.2", @@ -13453,7 +13763,6 @@ }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", @@ -13465,7 +13774,6 @@ }, "node_modules/@nodelib/fs.stat": { "version": "2.0.5", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -13473,7 +13781,6 @@ }, "node_modules/@nodelib/fs.walk": { "version": "1.2.8", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", @@ -13483,22 +13790,611 @@ "node": ">= 8" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "dev": true, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-arrow": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", + "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", + "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", + "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz", + "integrity": "sha512-QSxg29lfr/xcev6kSz7MAlmDnzbP1eI/Dwn3Tp1ip0KT5CUELsxkekFEMVBEoykI3oV39hKT4TKZzBNMbcTZYQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-escape-keydown": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-icons": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz", + "integrity": "sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==", + "license": "MIT", + "peerDependencies": { + "react": "^16.x || ^17.x || ^18.x" + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", + "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-popper/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.2.tgz", + "integrity": "sha512-WeDYLGPxJb/5EGBoedyJbT0MpoULmwnIPMJMSldkuiMsBAv7N1cRdsTWZWht9vpPOiN3qyiGAtbK2is47/uMFg==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.1.tgz", + "integrity": "sha512-IeFXVi4YS1K0wVZzXNrbaaUvIJ3qdY+/Ih4eHFhWA9SwGR9UDX7Ck8abvL57C4cv3wwMvUE0OG69Qc3NCcTe/A==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz", + "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-roving-focus/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-switch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.1.tgz", + "integrity": "sha512-diPqDDoBcZPSicYoMWdWx+bCPuTRH4QSp9J+65IvtdS0Kuzt67bI6n32vCj8q6NZmYW/ah+2orOtMwcX5eQwIg==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tabs": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.1.tgz", + "integrity": "sha512-3GBUDmP2DvzmtYLMsHmpA1GtR46ZDZ+OreXM/N+kkQJOPIgytFWWTfDQmBQKBvaFS0Vno0FktdbVzN28KGrMdw==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-roving-focus": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.3.tgz", + "integrity": "sha512-Z4w1FIS0BqVFI2c1jZvb/uDVJijJjJ2ZMuPV81oVgTZ7g3BZxobplnMVvXtFWgtozdvYJ+MFWtwkM5S2HnAong==", + "license": "MIT", + "dependencies": { + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", + "@radix-ui/react-dismissable-layer": "1.1.1", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.2", + "@radix-ui/react-presence": "1.1.1", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", + "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", + "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" + "dependencies": { + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@popperjs/core": { - "version": "2.11.8", - "license": "MIT", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/popperjs" - } + "node_modules/@radix-ui/rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==", + "license": "MIT" }, "node_modules/@reduxjs/toolkit": { "version": "1.9.7", @@ -14215,6 +15111,51 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, "node_modules/@types/cacheable-request": { "version": "6.0.3", "dev": true, @@ -14234,7 +15175,9 @@ } }, "node_modules/@types/estree": { - "version": "1.0.5", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", "license": "MIT" }, "node_modules/@types/estree-jsx": { @@ -14269,6 +15212,13 @@ "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/katex": { "version": "0.16.7", "license": "MIT" @@ -14389,12 +15339,249 @@ }, "node_modules/@types/vscode-webview": { "version": "1.57.5", + "dev": true, "license": "MIT" }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.9.0.tgz", + "integrity": "sha512-Y1n621OCy4m7/vTXNlCbMVp87zSd7NH0L9cXD8aIpOaNlzeWxIK4+Q19A68gSmTNRZn92UjocVUWDthGxtqHFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.9.0", + "@typescript-eslint/type-utils": "8.9.0", + "@typescript-eslint/utils": "8.9.0", + "@typescript-eslint/visitor-keys": "8.9.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^1.3.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.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.9.0.tgz", + "integrity": "sha512-U+BLn2rqTTHnc4FL3FJjxaXptTxmf9sNftJK62XLz4+GxG3hLHm/SUNaaXP5Y4uTiuYoL5YLy4JBCJe3+t8awQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/scope-manager": "8.9.0", + "@typescript-eslint/types": "8.9.0", + "@typescript-eslint/typescript-estree": "8.9.0", + "@typescript-eslint/visitor-keys": "8.9.0", + "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" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.9.0.tgz", + "integrity": "sha512-bZu9bUud9ym1cabmOYH9S6TnbWRzpklVmwqICeOulTCZ9ue2/pczWzQvt/cGj2r2o1RdKoZbuEMalJJSYw3pHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.9.0", + "@typescript-eslint/visitor-keys": "8.9.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.9.0.tgz", + "integrity": "sha512-JD+/pCqlKqAk5961vxCluK+clkppHY07IbV3vett97KOV+8C6l+CPEPwpUuiMwgbOz/qrN3Ke4zzjqbT+ls+1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.9.0", + "@typescript-eslint/utils": "8.9.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.9.0.tgz", + "integrity": "sha512-SjgkvdYyt1FAPhU9c6FiYCXrldwYYlIQLkuc+LfAhCna6ggp96ACncdtlbn8FmnG72tUkXclrDExOpEYf1nfJQ==", + "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.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.9.0.tgz", + "integrity": "sha512-9iJYTgKLDG6+iqegehc5+EqE6sqaee7kb8vWpmHZ86EqwDjmlqNNHeqDVqb9duh+BY6WCNHfIGvuVU3Tf9Db0g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@typescript-eslint/types": "8.9.0", + "@typescript-eslint/visitor-keys": "8.9.0", + "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": "^1.3.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.9.0.tgz", + "integrity": "sha512-PKgMmaSo/Yg/F7kIZvrgrWa1+Vwn036CdNUvYFEkYbPwOH4i8xvkaRlu148W3vtheWK9ckKRIz7PBP5oUlkrvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.9.0", + "@typescript-eslint/types": "8.9.0", + "@typescript-eslint/typescript-estree": "8.9.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" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.9.0.tgz", + "integrity": "sha512-Ht4y38ubk4L5/U8xKUBfKNYGmvKvA1CANoxiTRMM+tOLk3lbF3DvzZCxJCRSE+2GdCMSh6zq9VZJc3asc1XuAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.9.0", + "eslint-visitor-keys": "^3.4.3" + }, + "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": "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/@ungap/structured-clone": { "version": "1.2.0", "license": "ISC" }, + "node_modules/@vitejs/plugin-react": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.2.tgz", + "integrity": "sha512-hieu+o05v4glEBucTcKMK3dlES0OeJlD9YVOAPraVMOInBCwzumaIFiUjr4bHK7NPgnAHgiskUoceKercrN8vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.25.2", + "@babel/plugin-transform-react-jsx-self": "^7.24.7", + "@babel/plugin-transform-react-jsx-source": "^7.24.7", + "@types/babel__core": "^7.20.5", + "react-refresh": "^0.14.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "peerDependencies": { + "vite": "^4.2.0 || ^5.0.0" + } + }, "node_modules/@vitejs/plugin-react-swc": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.7.0.tgz", @@ -14407,6 +15594,29 @@ "vite": "^4 || ^5" } }, + "node_modules/acorn": { + "version": "8.12.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", + "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", + "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": "8.16.0", "license": "MIT", @@ -14430,6 +15640,8 @@ }, "node_modules/ansi-styles": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "license": "MIT", "dependencies": { "color-convert": "^1.9.0" @@ -14440,12 +15652,10 @@ }, "node_modules/any-promise": { "version": "1.3.0", - "dev": true, "license": "MIT" }, "node_modules/anymatch": { "version": "3.1.3", - "dev": true, "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", @@ -14476,7 +15686,6 @@ }, "node_modules/arg": { "version": "5.0.2", - "dev": true, "license": "MIT" }, "node_modules/argparse": { @@ -14555,7 +15764,6 @@ }, "node_modules/balanced-match": { "version": "1.0.2", - "dev": true, "license": "MIT" }, "node_modules/bcp-47-match": { @@ -14682,7 +15890,6 @@ }, "node_modules/binary-extensions": { "version": "2.3.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -14697,7 +15904,6 @@ }, "node_modules/brace-expansion": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" @@ -14705,7 +15911,6 @@ }, "node_modules/braces": { "version": "3.0.3", - "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -14715,7 +15920,9 @@ } }, "node_modules/browserslist": { - "version": "4.23.0", + "version": "4.24.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", + "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", "funding": [ { "type": "opencollective", @@ -14731,11 +15938,11 @@ } ], "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001587", - "electron-to-chromium": "^1.4.668", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.0.13" + "dependencies": { + "caniuse-lite": "^1.0.30001663", + "electron-to-chromium": "^1.5.28", + "node-releases": "^2.0.18", + "update-browserslist-db": "^1.1.0" }, "bin": { "browserslist": "cli.js" @@ -14783,9 +15990,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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/camelcase-css": { "version": "2.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -14799,7 +16015,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001628", + "version": "1.0.30001668", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001668.tgz", + "integrity": "sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw==", "funding": [ { "type": "opencollective", @@ -14826,6 +16044,8 @@ }, "node_modules/chalk": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", @@ -14838,6 +16058,8 @@ }, "node_modules/chalk/node_modules/escape-string-regexp": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "license": "MIT", "engines": { "node": ">=0.8.0" @@ -14877,7 +16099,6 @@ }, "node_modules/chokidar": { "version": "3.6.0", - "dev": true, "license": "MIT", "dependencies": { "anymatch": "~3.1.2", @@ -14900,7 +16121,6 @@ }, "node_modules/chokidar/node_modules/glob-parent": { "version": "5.1.2", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -14909,6 +16129,27 @@ "node": ">= 6" } }, + "node_modules/class-variance-authority": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz", + "integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==", + "license": "Apache-2.0", + "dependencies": { + "clsx": "2.0.0" + }, + "funding": { + "url": "https://joebell.co.uk" + } + }, + "node_modules/class-variance-authority/node_modules/clsx": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", + "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/classnames": { "version": "2.5.1", "license": "MIT" @@ -14928,8 +16169,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "license": "MIT", "dependencies": { "color-name": "1.1.3" @@ -14937,6 +16189,8 @@ }, "node_modules/color-name": { "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "license": "MIT" }, "node_modules/combined-stream": { @@ -14969,6 +16223,13 @@ "version": "2.0.4", "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/content-disposition": { "version": "0.5.4", "dev": true, @@ -14982,8 +16243,7 @@ }, "node_modules/convert-source-map": { "version": "2.0.0", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/core": { "resolved": "../core", @@ -14995,7 +16255,6 @@ }, "node_modules/cross-spawn": { "version": "7.0.3", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -15028,7 +16287,6 @@ }, "node_modules/cssesc": { "version": "3.0.0", - "dev": true, "license": "MIT", "bin": { "cssesc": "bin/cssesc" @@ -15092,6 +16350,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "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/defer-to-connect": { "version": "2.0.1", "dev": true, @@ -15126,113 +16391,406 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/didyoumean": { - "version": "1.2.2", + "node_modules/didyoumean": { + "version": "1.2.2", + "license": "Apache-2.0" + }, + "node_modules/direction": { + "version": "1.0.4", + "license": "MIT", + "bin": { + "direction": "cli.js" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/dlv": { + "version": "1.1.3", + "license": "MIT" + }, + "node_modules/dompurify": { + "version": "3.1.5", + "license": "(MPL-2.0 OR Apache-2.0)" + }, + "node_modules/downshift": { + "version": "7.6.2", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.14.8", + "compute-scroll-into-view": "^2.0.4", + "prop-types": "^15.7.2", + "react-is": "^17.0.2", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "react": ">=16.12.0" + } + }, + "node_modules/downshift/node_modules/react-is": { + "version": "17.0.2", + "license": "MIT" + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.38", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.38.tgz", + "integrity": "sha512-VbeVexmZ1IFh+5EfrYz1I0HTzHVIlJa112UEWhciPyeOcKJGeTv6N8WnG4wsQB81DGCaVEGhpSb6o6a8WYFXXg==", + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/engine.io-client": { + "version": "6.5.3", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.11.0", + "xmlhttprequest-ssl": "~2.0.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.2", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.12.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.12.0.tgz", + "integrity": "sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.11.0", + "@eslint/config-array": "^0.18.0", + "@eslint/core": "^0.6.0", + "@eslint/eslintrc": "^3.1.0", + "@eslint/js": "9.12.0", + "@eslint/plugin-kit": "^0.2.0", + "@humanfs/node": "^0.16.5", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.3.1", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.1.0", + "eslint-visitor-keys": "^4.1.0", + "espree": "^10.2.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", + "text-table": "^0.2.0" + }, + "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-plugin-react-hooks": { + "version": "5.1.0-rc-fb9a90fa48-20240614", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0-rc-fb9a90fa48-20240614.tgz", + "integrity": "sha512-xsiRwaDNF5wWNC4ZHLut+x/YcAxksUd9Rizt7LaEn3bV8VyYRpXnRJQlLOfYaVy9esk4DFP4zPPnoNVjq5Gc0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react-refresh": { + "version": "0.4.12", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.12.tgz", + "integrity": "sha512-9neVjoGv20FwYtCP6CB1dzR1vr57ZDNOXst21wd2xJ/cTlM2xLq0GWVlSNTdMn/4BtP6cHYBMCSp1wFBJ9jBsg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "eslint": ">=7" + } + }, + "node_modules/eslint-scope": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.1.0.tgz", + "integrity": "sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==", + "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": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.1.0.tgz", + "integrity": "sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==", + "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/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/eslint/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/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": "Apache-2.0" - }, - "node_modules/direction": { - "version": "1.0.4", "license": "MIT", - "bin": { - "direction": "cli.js" + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/dlv": { - "version": "1.1.3", + "node_modules/eslint/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==", "dev": true, - "license": "MIT" - }, - "node_modules/dompurify": { - "version": "3.1.5", - "license": "(MPL-2.0 OR Apache-2.0)" - }, - "node_modules/downshift": { - "version": "7.6.2", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.14.8", - "compute-scroll-into-view": "^2.0.4", - "prop-types": "^15.7.2", - "react-is": "^17.0.2", - "tslib": "^2.3.0" + "color-name": "~1.1.4" }, - "peerDependencies": { - "react": ">=16.12.0" + "engines": { + "node": ">=7.0.0" } }, - "node_modules/downshift/node_modules/react-is": { - "version": "17.0.2", - "license": "MIT" - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", + "node_modules/eslint/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==", "dev": true, "license": "MIT" }, - "node_modules/electron-to-chromium": { - "version": "1.4.790", - "license": "ISC" + "node_modules/eslint/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "node_modules/emoji-regex": { - "version": "8.0.0", + "node_modules/eslint/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/end-of-stream": { - "version": "1.4.4", + "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": "MIT", + "license": "ISC", "dependencies": { - "once": "^1.4.0" + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "node_modules/engine.io-client": { - "version": "6.5.3", + "node_modules/eslint/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": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1", - "engine.io-parser": "~5.2.1", - "ws": "~8.11.0", - "xmlhttprequest-ssl": "~2.0.0" - } - }, - "node_modules/engine.io-parser": { - "version": "5.2.2", - "license": "MIT", + "has-flag": "^4.0.0" + }, "engines": { - "node": ">=10.0.0" + "node": ">=8" } }, - "node_modules/entities": { - "version": "4.5.0", + "node_modules/espree": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.2.0.tgz", + "integrity": "sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==", + "dev": true, "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.12.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.1.0" + }, "engines": { - "node": ">=0.12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "url": "https://opencollective.com/eslint" } }, - "node_modules/escalade": { - "version": "3.1.2", - "license": "MIT", + "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": ">=6" + "node": ">=0.10" } }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "license": "MIT", - "engines": { - "node": ">=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" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "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/estree-util-is-identifier-name": { @@ -15243,6 +16801,16 @@ "url": "https://opencollective.com/unified" } }, + "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/execa": { "version": "0.7.0", "dev": true, @@ -15363,7 +16931,6 @@ }, "node_modules/fast-glob": { "version": "3.3.2", - "dev": true, "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -15378,7 +16945,6 @@ }, "node_modules/fast-glob/node_modules/glob-parent": { "version": "5.1.2", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -15387,9 +16953,22 @@ "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": "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/fastq": { "version": "1.17.1", - "dev": true, "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -15410,6 +16989,19 @@ "version": "0.4.8", "license": "MIT" }, + "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/file-type": { "version": "17.1.6", "dev": true, @@ -15455,7 +17047,6 @@ }, "node_modules/fill-range": { "version": "7.1.1", - "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -15464,6 +17055,23 @@ "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/find-versions": { "version": "5.1.0", "dev": true, @@ -15478,9 +17086,29 @@ "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.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "dev": true, + "license": "ISC" + }, "node_modules/foreground-child": { "version": "3.1.1", - "dev": true, "license": "ISC", "dependencies": { "cross-spawn": "^7.0.0", @@ -15538,7 +17166,6 @@ }, "node_modules/fsevents": { "version": "2.3.3", - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -15550,7 +17177,6 @@ }, "node_modules/function-bind": { "version": "1.1.2", - "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -15559,7 +17185,6 @@ "node_modules/gensync": { "version": "1.0.0-beta.2", "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } @@ -15574,7 +17199,6 @@ }, "node_modules/glob": { "version": "10.4.1", - "dev": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -15595,7 +17219,6 @@ }, "node_modules/glob-parent": { "version": "6.0.2", - "dev": true, "license": "ISC", "dependencies": { "is-glob": "^4.0.3" @@ -15605,10 +17228,16 @@ } }, "node_modules/globals": { - "version": "11.12.0", + "version": "15.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.11.0.tgz", + "integrity": "sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==", + "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/got": { @@ -15639,6 +17268,13 @@ "version": "4.2.11", "license": "ISC" }, + "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": "3.0.0", "license": "MIT", @@ -15648,7 +17284,6 @@ }, "node_modules/hasown": { "version": "2.0.2", - "dev": true, "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -16165,6 +17800,16 @@ ], "license": "BSD-3-Clause" }, + "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/immer": { "version": "9.0.21", "license": "MIT", @@ -16173,6 +17818,33 @@ "url": "https://opencollective.com/immer" } }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "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/inherits": { "version": "2.0.4", "dev": true, @@ -16204,7 +17876,6 @@ }, "node_modules/is-binary-path": { "version": "2.1.0", - "dev": true, "license": "MIT", "dependencies": { "binary-extensions": "^2.0.0" @@ -16236,7 +17907,6 @@ }, "node_modules/is-core-module": { "version": "2.13.1", - "dev": true, "license": "MIT", "dependencies": { "hasown": "^2.0.0" @@ -16255,7 +17925,6 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -16270,7 +17939,6 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -16289,7 +17957,6 @@ }, "node_modules/is-number": { "version": "7.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -16315,12 +17982,10 @@ }, "node_modules/isexe": { "version": "2.0.0", - "dev": true, "license": "ISC" }, "node_modules/jackspeak": { "version": "3.3.0", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -16337,7 +18002,6 @@ }, "node_modules/jiti": { "version": "1.21.3", - "dev": true, "license": "MIT", "bin": { "jiti": "bin/jiti.js" @@ -16347,14 +18011,29 @@ "version": "4.0.0", "license": "MIT" }, + "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/jsesc": { - "version": "2.5.2", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "node_modules/json-buffer": { @@ -16366,10 +18045,16 @@ "version": "1.0.0", "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/json5": { "version": "2.2.3", "license": "MIT", - "peer": true, "bin": { "json5": "lib/cli.js" }, @@ -16409,9 +18094,22 @@ "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": "2.1.0", - "dev": true, "license": "MIT", "engines": { "node": ">=10" @@ -16419,7 +18117,6 @@ }, "node_modules/lines-and-columns": { "version": "1.2.4", - "dev": true, "license": "MIT" }, "node_modules/linkify-it": { @@ -16429,10 +18126,33 @@ "uc.micro": "^2.0.0" } }, + "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": { "version": "4.17.21", "license": "MIT" }, + "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/lodash.truncate": { "version": "4.4.2", "license": "MIT" @@ -16482,6 +18202,15 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-react": { + "version": "0.452.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.452.0.tgz", + "integrity": "sha512-kNefjOUOGm+Mu3KDiryONyPba9r+nhcrz5oJs3N6JDzGboQNEXw5GB3yB8rnV9/FA4bPyggNU6CRSihZm9MvSw==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" + } + }, "node_modules/markdown-it": { "version": "14.1.0", "license": "MIT", @@ -16710,7 +18439,6 @@ }, "node_modules/merge2": { "version": "1.4.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 8" @@ -17135,7 +18863,6 @@ }, "node_modules/micromatch": { "version": "4.0.7", - "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -17182,7 +18909,6 @@ }, "node_modules/minimatch": { "version": "9.0.4", - "dev": true, "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -17196,7 +18922,6 @@ }, "node_modules/minipass": { "version": "7.1.2", - "dev": true, "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" @@ -17217,7 +18942,6 @@ }, "node_modules/mz": { "version": "2.7.0", - "dev": true, "license": "MIT", "dependencies": { "any-promise": "^1.0.0", @@ -17227,7 +18951,6 @@ }, "node_modules/nanoid": { "version": "3.3.7", - "dev": true, "funding": [ { "type": "github", @@ -17242,6 +18965,13 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "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/nice-napi": { "version": "1.0.2", "dev": true, @@ -17274,12 +19004,13 @@ } }, "node_modules/node-releases": { - "version": "2.0.14", + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", "license": "MIT" }, "node_modules/normalize-path": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -17345,7 +19076,6 @@ }, "node_modules/object-hash": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -17380,6 +19110,24 @@ "lru-cache": "^5.1.1" } }, + "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/orderedmap": { "version": "2.1.1", "license": "MIT" @@ -17411,6 +19159,51 @@ "node": ">=4" } }, + "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/parse-entities": { "version": "4.0.1", "license": "MIT", @@ -17443,9 +19236,18 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "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", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -17453,12 +19255,10 @@ }, "node_modules/path-parse": { "version": "1.0.7", - "dev": true, "license": "MIT" }, "node_modules/path-scurry": { "version": "1.11.1", - "dev": true, "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", @@ -17473,7 +19273,6 @@ }, "node_modules/path-scurry/node_modules/lru-cache": { "version": "10.2.2", - "dev": true, "license": "ISC", "engines": { "node": "14 || >=16.14" @@ -17492,7 +19291,9 @@ } }, "node_modules/picocolors": { - "version": "1.0.1", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", "license": "ISC" }, "node_modules/picomatch": { @@ -17507,7 +19308,6 @@ }, "node_modules/pify": { "version": "2.3.0", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -17515,7 +19315,6 @@ }, "node_modules/pirates": { "version": "4.0.6", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -17531,7 +19330,6 @@ }, "node_modules/postcss": { "version": "8.4.38", - "dev": true, "funding": [ { "type": "opencollective", @@ -17558,7 +19356,6 @@ }, "node_modules/postcss-import": { "version": "15.1.0", - "dev": true, "license": "MIT", "dependencies": { "postcss-value-parser": "^4.0.0", @@ -17574,7 +19371,6 @@ }, "node_modules/postcss-js": { "version": "4.0.1", - "dev": true, "license": "MIT", "dependencies": { "camelcase-css": "^2.0.1" @@ -17592,7 +19388,6 @@ }, "node_modules/postcss-load-config": { "version": "4.0.2", - "dev": true, "funding": [ { "type": "opencollective", @@ -17626,7 +19421,6 @@ }, "node_modules/postcss-load-config/node_modules/lilconfig": { "version": "3.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">=14" @@ -17637,7 +19431,6 @@ }, "node_modules/postcss-nested": { "version": "6.0.1", - "dev": true, "license": "MIT", "dependencies": { "postcss-selector-parser": "^6.0.11" @@ -17655,7 +19448,6 @@ }, "node_modules/postcss-selector-parser": { "version": "6.1.0", - "dev": true, "license": "MIT", "dependencies": { "cssesc": "^3.0.0", @@ -17685,6 +19477,16 @@ "url": "https://opencollective.com/preact" } }, + "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/prismjs": { "version": "1.29.0", "license": "MIT", @@ -17901,7 +19703,6 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", - "dev": true, "funding": [ { "type": "github", @@ -18052,6 +19853,16 @@ } } }, + "node_modules/react-refresh": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react-remark": { "version": "2.1.0", "license": "MIT", @@ -18428,7 +20239,6 @@ }, "node_modules/read-cache": { "version": "1.0.0", - "dev": true, "license": "MIT", "dependencies": { "pify": "^2.3.0" @@ -18464,7 +20274,6 @@ }, "node_modules/readdirp": { "version": "3.6.0", - "dev": true, "license": "MIT", "dependencies": { "picomatch": "^2.2.1" @@ -18774,7 +20583,6 @@ }, "node_modules/resolve": { "version": "1.22.8", - "dev": true, "license": "MIT", "dependencies": { "is-core-module": "^2.13.0", @@ -18793,6 +20601,16 @@ "dev": true, "license": "MIT" }, + "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/responselike": { "version": "2.0.1", "dev": true, @@ -18806,7 +20624,6 @@ }, "node_modules/reusify": { "version": "1.0.4", - "dev": true, "license": "MIT", "engines": { "iojs": ">=1.0.0", @@ -18834,7 +20651,6 @@ }, "node_modules/run-parallel": { "version": "1.2.0", - "dev": true, "funding": [ { "type": "github", @@ -18882,8 +20698,9 @@ }, "node_modules/semver": { "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" } @@ -18934,7 +20751,6 @@ }, "node_modules/shebang-command": { "version": "2.0.0", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -18945,7 +20761,6 @@ }, "node_modules/shebang-regex": { "version": "3.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -18953,7 +20768,6 @@ }, "node_modules/signal-exit": { "version": "4.1.0", - "dev": true, "license": "ISC", "engines": { "node": ">=14" @@ -19076,7 +20890,6 @@ }, "node_modules/source-map-js": { "version": "1.2.0", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -19117,7 +20930,6 @@ "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -19153,7 +20965,6 @@ "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -19178,6 +20989,19 @@ "node": ">=6" } }, + "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/strip-outer": { "version": "2.0.0", "dev": true, @@ -19242,7 +21066,6 @@ }, "node_modules/sucrase": { "version": "3.35.0", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", @@ -19263,7 +21086,6 @@ }, "node_modules/sucrase/node_modules/commander": { "version": "4.1.1", - "dev": true, "license": "MIT", "engines": { "node": ">= 6" @@ -19281,7 +21103,6 @@ }, "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -19304,9 +21125,18 @@ "node": ">=10.0.0" } }, + "node_modules/tailwind-merge": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.4.tgz", + "integrity": "sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/dcastil" + } + }, "node_modules/tailwindcss": { "version": "3.4.3", - "dev": true, "license": "MIT", "dependencies": { "@alloc/quick-lru": "^5.2.0", @@ -19340,9 +21170,24 @@ "node": ">=14.0.0" } }, + "node_modules/tailwindcss-animate": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", + "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", + "license": "MIT", + "peerDependencies": { + "tailwindcss": ">=3.0.0 || insiders" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "dev": true, + "license": "MIT" + }, "node_modules/thenify": { "version": "3.3.1", - "dev": true, "license": "MIT", "dependencies": { "any-promise": "^1.0.0" @@ -19350,7 +21195,6 @@ }, "node_modules/thenify-all": { "version": "1.6.0", - "dev": true, "license": "MIT", "dependencies": { "thenify": ">= 3.1.0 < 4" @@ -19375,7 +21219,6 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", - "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -19438,15 +21281,40 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" + } + }, "node_modules/ts-interface-checker": { "version": "0.1.13", - "dev": true, "license": "Apache-2.0" }, "node_modules/tslib": { "version": "2.6.3", "license": "0BSD" }, + "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/typescript": { "version": "4.9.5", "dev": true, @@ -19459,6 +21327,30 @@ "node": ">=4.2.0" } }, + "node_modules/typescript-eslint": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.9.0.tgz", + "integrity": "sha512-AuD/FXGYRQyqyOBCpNLldMlsCGvmDNxptQ3Dp58/NXeB+FqyvTfXmMyba3PYa0Vi9ybnj7G8S/yd/4Cw8y47eA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.9.0", + "@typescript-eslint/parser": "8.9.0", + "@typescript-eslint/utils": "8.9.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/uc.micro": { "version": "2.1.0", "license": "MIT" @@ -19591,7 +21483,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.16", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", "funding": [ { "type": "opencollective", @@ -19608,8 +21502,8 @@ ], "license": "MIT", "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" + "escalade": "^3.2.0", + "picocolors": "^1.1.0" }, "bin": { "update-browserslist-db": "cli.js" @@ -19634,7 +21528,6 @@ }, "node_modules/util-deprecate": { "version": "1.0.2", - "dev": true, "license": "MIT" }, "node_modules/uuid": { @@ -20149,7 +22042,6 @@ }, "node_modules/which": { "version": "2.0.2", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -20161,9 +22053,18 @@ "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/wrap-ansi": { "version": "8.1.0", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", @@ -20180,7 +22081,6 @@ "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", - "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -20196,7 +22096,6 @@ }, "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { "version": "4.3.0", - "dev": true, "license": "MIT", "dependencies": { "color-convert": "^2.0.1" @@ -20210,7 +22109,6 @@ }, "node_modules/wrap-ansi-cjs/node_modules/color-convert": { "version": "2.0.1", - "dev": true, "license": "MIT", "dependencies": { "color-name": "~1.1.4" @@ -20221,12 +22119,10 @@ }, "node_modules/wrap-ansi-cjs/node_modules/color-name": { "version": "1.1.4", - "dev": true, "license": "MIT" }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -20237,7 +22133,6 @@ }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "6.2.1", - "dev": true, "license": "MIT", "engines": { "node": ">=12" @@ -20248,12 +22143,10 @@ }, "node_modules/wrap-ansi/node_modules/emoji-regex": { "version": "9.2.2", - "dev": true, "license": "MIT" }, "node_modules/wrap-ansi/node_modules/string-width": { "version": "5.1.2", - "dev": true, "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", @@ -20269,7 +22162,6 @@ }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "7.1.0", - "dev": true, "license": "MIT", "dependencies": { "ansi-regex": "^6.0.1" @@ -20324,7 +22216,6 @@ }, "node_modules/yaml": { "version": "2.4.3", - "dev": true, "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -20333,6 +22224,19 @@ "node": ">= 14" } }, + "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/zwitch": { "version": "2.0.4", "license": "MIT", diff --git a/gui/package.json b/gui/package.json index 0d4ab0fd55..982fecc05d 100644 --- a/gui/package.json +++ b/gui/package.json @@ -10,6 +10,16 @@ "preview": "vite preview" }, "dependencies": { + "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-switch": "^1.1.1", + "@radix-ui/react-tabs": "^1.1.1", + "@radix-ui/react-tooltip": "^1.1.3", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "lucide-react": "^0.452.0", + "tailwind-merge": "^2.5.3", + "tailwindcss-animate": "^1.0.7", "@headlessui/react": "^1.7.17", "@heroicons/react": "^2.0.18", "@monaco-editor/react": "^4.6.0", @@ -80,7 +90,15 @@ "postcss": "^8.4.21", "tailwindcss": "^3.2.7", "typescript": "^4.9.3", - "vite": "^4.1.0" + "vite": "^4.1.0", + "@eslint/js": "^9.11.1", + "@types/vscode-webview": "^1.57.5", + "@vitejs/plugin-react": "^4.3.2", + "eslint": "^9.11.1", + "eslint-plugin-react-hooks": "^5.1.0-rc.0", + "eslint-plugin-react-refresh": "^0.4.12", + "globals": "^15.9.0", + "typescript-eslint": "^8.7.0" }, "engine-strict": true, "engines": { diff --git a/gui/src/App.tsx b/gui/src/App.tsx index f72f9aaa8e..5bef3e172e 100644 --- a/gui/src/App.tsx +++ b/gui/src/App.tsx @@ -19,6 +19,7 @@ import LocalOnboarding from "./pages/onboarding/LocalOnboarding"; import Onboarding from "./pages/onboarding/Onboarding"; import SettingsPage from "./pages/settings"; import Stats from "./pages/stats"; +import Inventory from "./pages/inventory"; const router = createMemoryRouter([ { @@ -86,6 +87,10 @@ const router = createMemoryRouter([ path: "/apiKeyAutocompleteOnboarding", element: , }, + { + path: "/inventory", + element: + } ], }, ]); diff --git a/gui/src/components/Layout.tsx b/gui/src/components/Layout.tsx index 317f45d8ee..f72932b0c9 100644 --- a/gui/src/components/Layout.tsx +++ b/gui/src/components/Layout.tsx @@ -118,6 +118,7 @@ const HIDE_FOOTER_ON_PAGES = [ "/onboarding", "/localOnboarding", "/apiKeyOnboarding", + "/inventory" ]; const SHOW_SHORTCUTS_ON_PAGES = ["/"]; diff --git a/gui/src/components/ui/button.tsx b/gui/src/components/ui/button.tsx new file mode 100644 index 0000000000..0270f644a8 --- /dev/null +++ b/gui/src/components/ui/button.tsx @@ -0,0 +1,57 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const buttonVariants = cva( + "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50", + { + variants: { + variant: { + default: + "bg-primary text-primary-foreground shadow hover:bg-primary/90", + destructive: + "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90", + outline: + "border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground", + secondary: + "bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80", + ghost: "hover:bg-accent hover:text-accent-foreground", + link: "text-primary underline-offset-4 hover:underline", + }, + size: { + default: "h-9 px-4 py-2", + sm: "h-8 rounded-md px-3 text-xs", + lg: "h-10 rounded-md px-8", + icon: "h-9 w-9", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + } +) + +export interface ButtonProps + extends React.ButtonHTMLAttributes, + VariantProps { + asChild?: boolean +} + +const Button = React.forwardRef( + ({ className, variant, size, asChild = false, ...props }, ref) => { + const Comp = asChild ? Slot : "button" + return ( + + ) + } +) +Button.displayName = "Button" + +export { Button, buttonVariants } diff --git a/gui/src/components/ui/card.tsx b/gui/src/components/ui/card.tsx new file mode 100644 index 0000000000..77e9fb789b --- /dev/null +++ b/gui/src/components/ui/card.tsx @@ -0,0 +1,76 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +const Card = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +Card.displayName = "Card" + +const CardHeader = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardHeader.displayName = "CardHeader" + +const CardTitle = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardTitle.displayName = "CardTitle" + +const CardDescription = React.forwardRef< + HTMLParagraphElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardDescription.displayName = "CardDescription" + +const CardContent = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +

+)) +CardContent.displayName = "CardContent" + +const CardFooter = React.forwardRef< + HTMLDivElement, + React.HTMLAttributes +>(({ className, ...props }, ref) => ( +
+)) +CardFooter.displayName = "CardFooter" + +export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent } diff --git a/gui/src/components/ui/input.tsx b/gui/src/components/ui/input.tsx new file mode 100644 index 0000000000..5af26b2c1a --- /dev/null +++ b/gui/src/components/ui/input.tsx @@ -0,0 +1,25 @@ +import * as React from "react" + +import { cn } from "@/lib/utils" + +export interface InputProps + extends React.InputHTMLAttributes {} + +const Input = React.forwardRef( + ({ className, type, ...props }, ref) => { + return ( + + ) + } +) +Input.displayName = "Input" + +export { Input } diff --git a/gui/src/components/ui/switch.tsx b/gui/src/components/ui/switch.tsx new file mode 100644 index 0000000000..2f5f6d74a6 --- /dev/null +++ b/gui/src/components/ui/switch.tsx @@ -0,0 +1,27 @@ +import * as React from "react" +import * as SwitchPrimitives from "@radix-ui/react-switch" + +import { cn } from "@/lib/utils" + +const Switch = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)) +Switch.displayName = SwitchPrimitives.Root.displayName + +export { Switch } diff --git a/gui/src/components/ui/tabs.tsx b/gui/src/components/ui/tabs.tsx new file mode 100644 index 0000000000..cd407bba7f --- /dev/null +++ b/gui/src/components/ui/tabs.tsx @@ -0,0 +1,53 @@ +import * as React from "react"; +import * as TabsPrimitive from "@radix-ui/react-tabs"; + +import { cn } from "@/lib/utils"; + +const Tabs = TabsPrimitive.Root; + +const TabsList = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +TabsList.displayName = TabsPrimitive.List.displayName; + +const TabsTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +TabsTrigger.displayName = TabsPrimitive.Trigger.displayName; + +const TabsContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)); +TabsContent.displayName = TabsPrimitive.Content.displayName; + +export { Tabs, TabsList, TabsTrigger, TabsContent }; diff --git a/gui/src/components/ui/tooltip.tsx b/gui/src/components/ui/tooltip.tsx new file mode 100644 index 0000000000..a9c71baa29 --- /dev/null +++ b/gui/src/components/ui/tooltip.tsx @@ -0,0 +1,28 @@ +import * as React from "react" +import * as TooltipPrimitive from "@radix-ui/react-tooltip" + +import { cn } from "@/lib/utils" + +const TooltipProvider = TooltipPrimitive.Provider + +const Tooltip = TooltipPrimitive.Root + +const TooltipTrigger = TooltipPrimitive.Trigger + +const TooltipContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, sideOffset = 4, ...props }, ref) => ( + +)) +TooltipContent.displayName = TooltipPrimitive.Content.displayName + +export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } diff --git a/gui/src/inventory/main.tsx b/gui/src/inventory/main.tsx new file mode 100644 index 0000000000..1c84476b4a --- /dev/null +++ b/gui/src/inventory/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from 'react' +import { createRoot } from 'react-dom/client' +import Inventory from '../pages/inventory.js' +import './index.css' + +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/gui/src/inventory/pages/InventoryPage.tsx b/gui/src/inventory/pages/InventoryPage.tsx new file mode 100644 index 0000000000..494c1b5aa5 --- /dev/null +++ b/gui/src/inventory/pages/InventoryPage.tsx @@ -0,0 +1,344 @@ +import { useState } from 'react' +import { Search, Star, X } from 'lucide-react' +import { Input } from "@/components/ui/input" +import { Switch } from "@/components/ui/switch" +import { Button } from "@/components/ui/button" +import { Card, CardContent } from "@/components/ui/card" +import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" + +interface AITool { + id: string + name: string + description: string + icon: string + whenToUse: string + strengths: string[] + weaknesses: string[] + enabled: boolean + comingSoon?: boolean +} + +const initialTools: AITool[] = [ + { + id: "1", + name: "Search (Perplexity)", + description: + "AI-powered search engine: up-to-date information for docs, libraries, etc.", + icon: "🔍", + whenToUse: + "When you need to find information where the latest, most up-to-date version is important, e.g. documentation, software libraries, etc. Regular LLMs' knowledge are outdated by several months, so they will not be as good as Perplexity for such use cases", + strengths: [ + "Most up-to-date information", + "Non coding specific questions are also supported", + "Provides cited sources", + ], + weaknesses: [ + "May be wordy and verbose", + "Not specialized for pure code generation", + ], + enabled: true, + }, + { + id: "2", + name: "AI Chat (Continue)", + description: "AI pair programmer for flexible coding assistance", + icon: "👨‍💻", + whenToUse: + "When you need fragmented coding assistance and suggestions. Ask the chat any question, it can generate code decently well and also create files. Requires medium human intervention to apply and review changes.", + strengths: [ + "AI chat (CMD/CTRL+L and CMD/CTRL+I)", + "Context-aware suggestions", + "Code and file generation", + "Flexibility on choosing what you want to keep and discard from suggestions", + ], + weaknesses: [ + "The flexibility also means it requires at least a medium level of human intervention", + ], + enabled: true, + }, + { + id: "3", + name: "Memory (mem0)", + description: "Personalization: let the AI remember your past thoughts", + icon: "📝", + whenToUse: + "When you want the AI to remember insights from past prompts you've given it. It can automatically remember details like what version of for e.g. Python you're using, or other specific details of your codebase, like your coding styles, or your expertise level", + strengths: [ + "Intelligent memory of your coding profile", + "Increase in accuracy of results due to personalization", + ], + weaknesses: [ + "Requires you to remove expired memories manually that are no longer relevant", + "Requires PearAI server due to essential custom logic", + ], + enabled: false, + }, + { + id: "4", + name: "Creator (aider)", + description: '"No-code" assistant: complete features zero to one directly', + icon: "🤖", + whenToUse: + "When you need a feature or bug fixes investigated, or completed directly. Requires lower human intervention.", + strengths: [ + "Zero to one feature completions", + "Automated refactoring", + "Lower level of human intervention needed", + ], + weaknesses: [ + "Lower level of human intervention needed means less flexibility on what to keep and discard from suggestions", + ], + enabled: true, + }, + { + id: "5", + name: "Painter (DALL-E)", + description: "AI image generation from textual descriptions", + icon: "🎨", + whenToUse: + "Use when you need to create unique images based on text prompts", + strengths: [ + "Creative image generation", + "Wide range of styles", + "Quick results", + ], + weaknesses: [ + "May misinterpret complex prompts", + "Limited control over specific details", + ], + enabled: false, + comingSoon: true, + }, +]; + +const suggestedBuild = ["1", "2", "4"]; // IDs of suggested tools + +function AIToolCard({ + tool, + onClick, + onToggle, +}: { + tool: AITool; + onClick: () => void; + onToggle: () => void; +}) { + return ( + + +
+
{tool.icon}
+ +
+

+ {tool.name} +

+

+ {tool.comingSoon ? "Coming soon" : tool.description} +

+
+
+ ); +} + +function QuickActionSlot({ + tool, + onRemove, +}: { + tool: AITool | null; + onRemove: () => void; +}) { + return ( +
+ {tool ? ( + <> +
{tool.icon}
+
+ {tool.name} +
+ + + ) : ( +
Empty
+ )} +
+ ); +} + +export default function AIToolInventory() { + const [tools, setTools] = useState(initialTools); + const [searchQuery, setSearchQuery] = useState(""); + const [focusedTool, setFocusedTool] = useState(null); + const [quickSlots, setQuickSlots] = useState<(AITool | null)[]>([ + null, + null, + null, + null, + ]); + + const filteredTools = tools.filter((tool) => + tool.name.toLowerCase().includes(searchQuery.toLowerCase()), + ); + + const handleToggle = (id: string) => { + setTools( + tools.map((tool) => + tool.id === id ? { ...tool, enabled: !tool.enabled } : tool, + ), + ); + }; + + const handleEquipToQuickSlot = (tool: AITool) => { + const emptySlotIndex = quickSlots.findIndex((slot) => slot === null); + if ( + emptySlotIndex !== -1 && + !quickSlots.find((slot) => slot?.id === tool.id) + ) { + const newQuickSlots = [...quickSlots]; + newQuickSlots[emptySlotIndex] = tool; + setQuickSlots(newQuickSlots); + } + }; + + const handleRemoveFromQuickSlot = (index: number) => { + const newQuickSlots = [...quickSlots]; + newQuickSlots[index] = null; + setQuickSlots(newQuickSlots); + }; + + return ( + +
+
+

PearAI Inventory

+
+ + setSearchQuery(e.target.value)} + className="pl-10 w-full bg-input text-foreground border-input" + aria-label="Search AI tools" + /> +
+
+ +
+
+
+
+ {filteredTools.map((tool) => ( + setFocusedTool(tool)} + onToggle={() => handleToggle(tool.id)} + /> + ))} +
+
+
+ +
+ {focusedTool ? ( +
+

+ {focusedTool.name} {focusedTool.icon} +

+

{focusedTool.description}

+

When to use:

+

{focusedTool.whenToUse}

+

Strengths:

+
    + {focusedTool.strengths.map((strength, index) => ( +
  • {strength}
  • + ))} +
+

Weaknesses:

+
    + {focusedTool.weaknesses.map((weakness, index) => ( +
  • {weakness}
  • + ))} +
+ {!focusedTool.comingSoon && ( +
+ + {quickSlots.every((slot) => slot !== null) && ( +

+ Quick action slots are full +

+ )} +
+ )} +
+ ) : ( +
+ Select an AI tool to view details +
+ )} +
+
+ +
+

Quick Action Slots

+
+ {quickSlots.map((slot, index) => ( + handleRemoveFromQuickSlot(index)} + /> + ))} +
+
+ + Suggested Build: +
+ {suggestedBuild.map((id) => { + const tool = tools.find((t) => t.id === id); + return tool ? ( + + +
+ {tool.icon} + {tool.name} +
+
+ +

{tool.description}

+
+
+ ) : null; + })} +
+
+
+
+
+ ); +} diff --git a/gui/src/inventory/utilities/vscode.ts b/gui/src/inventory/utilities/vscode.ts new file mode 100644 index 0000000000..3423758015 --- /dev/null +++ b/gui/src/inventory/utilities/vscode.ts @@ -0,0 +1,79 @@ +import type { WebviewApi } from "vscode-webview"; + +const PEAR_AI_STATE_KEY = "PearAIStateKey" +/** + * A utility wrapper around the acquireVsCodeApi() function, which enables + * message passing and state management between the webview and extension + * contexts. + * + * This utility also enables webview code to be run in a web browser-based + * dev server by using native web browser features that mock the functionality + * enabled by acquireVsCodeApi. + */ +class VSCodeAPIWrapper { + private readonly vsCodeApi: WebviewApi | undefined; + + constructor() { + // Check if the acquireVsCodeApi function exists in the current development + // context (i.e. VS Code development window or web browser) + if (typeof acquireVsCodeApi === "function") { + this.vsCodeApi = acquireVsCodeApi(); + } + } + + /** + * Post a message (i.e. send arbitrary data) to the owner of the webview. + * + * @remarks When running webview code inside a web browser, postMessage will instead + * log the given message to the console. + * + * @param message Abitrary data (must be JSON serializable) to send to the extension context. + */ + public postMessage(message: unknown) { + if (this.vsCodeApi) { + this.vsCodeApi.postMessage(message); + } else { + console.log(message); + } + } + + /** + * Get the persistent state stored for this webview. + * + * @remarks When running webview source code inside a web browser, getState will retrieve state + * from local storage (https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage). + * + * @return The current state or `undefined` if no state has been set. + */ + public getState(): unknown | undefined { + if (this.vsCodeApi) { + return this.vsCodeApi.getState(); + } else { + const state = localStorage.getItem(PEAR_AI_STATE_KEY); + return state ? JSON.parse(state) : undefined; + } + } + + /** + * Set the persistent state stored for this webview. + * + * @remarks When running webview source code inside a web browser, setState will set the given + * state using local storage (https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage). + * + * @param newState New persisted state. This must be a JSON serializable object. Can be retrieved + * using {@link getState}. + * + * @return The new state. + */ + public setState(newState: T): T { + if (this.vsCodeApi) { + return this.vsCodeApi.setState(newState); + } else { + localStorage.setItem(PEAR_AI_STATE_KEY, JSON.stringify(newState)); + return newState; + } + } +} + +// Exports class singleton to prevent multiple invocations of acquireVsCodeApi. +export const vscode = new VSCodeAPIWrapper(); \ No newline at end of file diff --git a/gui/src/pages/gui.tsx b/gui/src/pages/gui.tsx index 5e7cb60525..9d6a3fb8f3 100644 --- a/gui/src/pages/gui.tsx +++ b/gui/src/pages/gui.tsx @@ -545,6 +545,14 @@ function GUI() { > New Session ({getMetaKeyLabel()} {isJetBrains() ? "J" : "L"}) {" "} + { + navigate("/inventory"); + }} + className="mr-auto" + > + Inventory + {" "}
) : ( <> diff --git a/gui/src/pages/inventory.tsx b/gui/src/pages/inventory.tsx new file mode 100644 index 0000000000..8bbe2e5e55 --- /dev/null +++ b/gui/src/pages/inventory.tsx @@ -0,0 +1,52 @@ +import InventoryPage from "../inventory/pages/InventoryPage"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import Gui from "./gui"; + +const TemplateComponent = ({ name }: { name: string }) => { + return ( +
+ {name} here +
+ ); +}; + +const tabs = [ + { + id: "aider", + name: "Creator (aider)", + component: , + }, + { id: "inventory", name: "Inventory", component: }, + { + id: "perplexity", + name: "Search (Perplexity)", + component: , + }, +]; + +export default function Inventory() { + return ( +
+ +
+ + {tabs.map((tab) => ( + + {tab.name} + + ))} + +
+ {tabs.map((tab) => ( + + {tab.component} + + ))} +
+
+ ); +} diff --git a/gui/tailwind.config.cjs b/gui/tailwind.config.cjs index 269b57ef1a..a0b4840a3e 100644 --- a/gui/tailwind.config.cjs +++ b/gui/tailwind.config.cjs @@ -13,7 +13,7 @@ module.exports = { "secondary-dark": "rgb(var(--secondary-dark) / )", }, }, - plugins: [], + plugins: [require("tailwindcss-animate")], corePlugins: { preflight: false, }, diff --git a/gui/tsconfig.json b/gui/tsconfig.json index 7977a2e1c2..09b100dcc5 100644 --- a/gui/tsconfig.json +++ b/gui/tsconfig.json @@ -15,7 +15,10 @@ "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", - "noEmitOnError": false + "noEmitOnError": false, + "paths": { + "@/*": ["./src/*"] + } }, "include": ["src", "../src/util/messenger.ts"], "references": [{ "path": "./tsconfig.node.json" }] diff --git a/gui/vite.config.ts b/gui/vite.config.ts index fdc63bbdb8..bfde22f8cc 100644 --- a/gui/vite.config.ts +++ b/gui/vite.config.ts @@ -1,3 +1,4 @@ +import path from "path" import react from "@vitejs/plugin-react-swc"; import tailwindcss from "tailwindcss"; import { defineConfig } from "vite"; @@ -16,4 +17,9 @@ export default defineConfig({ }, }, }, + resolve: { + alias: { + "@": path.resolve(__dirname, "./src"), + }, + }, }); From 6486a8974aff3cb3f92df6a26f4dcc27d81f0a49 Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Wed, 16 Oct 2024 20:53:58 -0700 Subject: [PATCH 02/18] PearAI Inventory theming fixes --- docs/static/schemas/config.json | 2 +- .../src/main/resources/config_schema.json | 2 +- extensions/vscode/continue_rc_schema.json | 2 +- extensions/vscode/package-lock.json | 2 +- gui/package-lock.json | 6 +- gui/package.json | 33 +- gui/src/App.tsx | 4 +- gui/src/components/ui/button.tsx | 7 +- gui/src/components/ui/switch.tsx | 8 +- gui/src/index.css | 57 +- gui/src/inventory/main.tsx | 10 - gui/src/inventory/pages/InventoryPage.tsx | 621 +++++++++--------- gui/src/pages/gui.tsx | 5 +- gui/src/pages/inventory.tsx | 2 +- gui/src/vscode-webview.d.ts | 7 + gui/tailwind.config.cjs | 37 +- gui/tsconfig.json | 3 +- 17 files changed, 449 insertions(+), 359 deletions(-) delete mode 100644 gui/src/inventory/main.tsx create mode 100644 gui/src/vscode-webview.d.ts diff --git a/docs/static/schemas/config.json b/docs/static/schemas/config.json index 3ed4cce716..7e45c68601 100644 --- a/docs/static/schemas/config.json +++ b/docs/static/schemas/config.json @@ -1291,7 +1291,7 @@ "Write a custom slash command at your own HTTP endpoint. Set 'url' in the params object for the endpoint you have setup.", "Generate a commit message for the current changes", "Review code and give feedback", - "Generate a React component using v0" + "Generate a component using v0" ] }, { diff --git a/extensions/intellij/src/main/resources/config_schema.json b/extensions/intellij/src/main/resources/config_schema.json index 3ed4cce716..7e45c68601 100644 --- a/extensions/intellij/src/main/resources/config_schema.json +++ b/extensions/intellij/src/main/resources/config_schema.json @@ -1291,7 +1291,7 @@ "Write a custom slash command at your own HTTP endpoint. Set 'url' in the params object for the endpoint you have setup.", "Generate a commit message for the current changes", "Review code and give feedback", - "Generate a React component using v0" + "Generate a component using v0" ] }, { diff --git a/extensions/vscode/continue_rc_schema.json b/extensions/vscode/continue_rc_schema.json index 914bbbc492..996a2fc3b8 100644 --- a/extensions/vscode/continue_rc_schema.json +++ b/extensions/vscode/continue_rc_schema.json @@ -1427,7 +1427,7 @@ "Write a custom slash command at your own HTTP endpoint. Set 'url' in the params object for the endpoint you have setup.", "Generate a commit message for the current changes", "Review code and give feedback", - "Generate a React component using v0" + "Generate a component using v0" ] }, { diff --git a/extensions/vscode/package-lock.json b/extensions/vscode/package-lock.json index 5dd3c05339..fc27f39b6d 100644 --- a/extensions/vscode/package-lock.json +++ b/extensions/vscode/package-lock.json @@ -6,8 +6,8 @@ "packages": { "": { "name": "pearai", - "license": "Apache-2.0", "version": "1.3.0", + "license": "Apache-2.0", "dependencies": { "@electron/rebuild": "^3.2.10", "@reduxjs/toolkit": "^1.9.3", diff --git a/gui/package-lock.json b/gui/package-lock.json index 7d5bde64e6..a7fa4c6426 100644 --- a/gui/package-lock.json +++ b/gui/package-lock.json @@ -29,7 +29,6 @@ "@tiptap/react": "^2.1.13", "@tiptap/starter-kit": "^2.1.13", "@tiptap/suggestion": "^2.1.13", - "@types/vscode-webview": "^1.57.1", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "core": "file:../core", @@ -15339,8 +15338,9 @@ }, "node_modules/@types/vscode-webview": { "version": "1.57.5", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@types/vscode-webview/-/vscode-webview-1.57.5.tgz", + "integrity": "sha512-iBAUYNYkz+uk1kdsq05fEcoh8gJmwT3lqqFPN7MGyjQ3HVloViMdo7ZJ8DFIP8WOK74PjOEilosqAyxV2iUFUw==", + "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.9.0", diff --git a/gui/package.json b/gui/package.json index 982fecc05d..b74f955eca 100644 --- a/gui/package.json +++ b/gui/package.json @@ -10,19 +10,14 @@ "preview": "vite preview" }, "dependencies": { + "@headlessui/react": "^1.7.17", + "@heroicons/react": "^2.0.18", + "@monaco-editor/react": "^4.6.0", "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-slot": "^1.1.0", "@radix-ui/react-switch": "^1.1.1", "@radix-ui/react-tabs": "^1.1.1", "@radix-ui/react-tooltip": "^1.1.3", - "class-variance-authority": "^0.7.0", - "clsx": "^2.1.1", - "lucide-react": "^0.452.0", - "tailwind-merge": "^2.5.3", - "tailwindcss-animate": "^1.0.7", - "@headlessui/react": "^1.7.17", - "@heroicons/react": "^2.0.18", - "@monaco-editor/react": "^4.6.0", "@reduxjs/toolkit": "^1.9.3", "@tiptap/core": "^2.3.2", "@tiptap/extension-document": "^2.3.2", @@ -37,11 +32,13 @@ "@tiptap/react": "^2.1.13", "@tiptap/starter-kit": "^2.1.13", "@tiptap/suggestion": "^2.1.13", - "@types/vscode-webview": "^1.57.1", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", "core": "file:../core", "dompurify": "^3.0.6", "downshift": "^7.6.0", "lodash": "^4.17.21", + "lucide-react": "^0.452.0", "minisearch": "^6.3.0", "onigasm": "^2.2.5", "posthog-js": "^1.130.1", @@ -69,12 +66,15 @@ "socket.io-client": "^4.7.2", "styled-components": "^5.3.6", "table": "^6.8.1", + "tailwind-merge": "^2.5.3", + "tailwindcss-animate": "^1.0.7", "tippy.js": "^6.3.7", "unist-util-visit": "^5.0.0", "uuid": "^9.0.1", "vscode-webview": "^1.0.1-beta.1" }, "devDependencies": { + "@eslint/js": "^9.11.1", "@swc/cli": "^0.3.14", "@swc/core": "^1.7.2", "@types/lodash": "^4.17.6", @@ -85,20 +85,19 @@ "@types/react-router-dom": "^5.3.3", "@types/react-syntax-highlighter": "^15.5.7", "@types/styled-components": "^5.1.26", - "@vitejs/plugin-react-swc": "^3.7.0", - "autoprefixer": "^10.4.13", - "postcss": "^8.4.21", - "tailwindcss": "^3.2.7", - "typescript": "^4.9.3", - "vite": "^4.1.0", - "@eslint/js": "^9.11.1", "@types/vscode-webview": "^1.57.5", "@vitejs/plugin-react": "^4.3.2", + "@vitejs/plugin-react-swc": "^3.7.0", + "autoprefixer": "^10.4.13", "eslint": "^9.11.1", "eslint-plugin-react-hooks": "^5.1.0-rc.0", "eslint-plugin-react-refresh": "^0.4.12", "globals": "^15.9.0", - "typescript-eslint": "^8.7.0" + "postcss": "^8.4.21", + "tailwindcss": "^3.2.7", + "typescript": "^4.9.3", + "typescript-eslint": "^8.7.0", + "vite": "^4.1.0" }, "engine-strict": true, "engines": { diff --git a/gui/src/App.tsx b/gui/src/App.tsx index 5bef3e172e..591a998a79 100644 --- a/gui/src/App.tsx +++ b/gui/src/App.tsx @@ -89,8 +89,8 @@ const router = createMemoryRouter([ }, { path: "/inventory", - element: - } + element: , + }, ], }, ]); diff --git a/gui/src/components/ui/button.tsx b/gui/src/components/ui/button.tsx index 0270f644a8..2d6a57b780 100644 --- a/gui/src/components/ui/button.tsx +++ b/gui/src/components/ui/button.tsx @@ -9,8 +9,7 @@ const buttonVariants = cva( { variants: { variant: { - default: - "bg-primary text-primary-foreground shadow hover:bg-primary/90", + default: "bg-button text-button-foreground shadow hover:bg-button/90", destructive: "bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90", outline: @@ -31,8 +30,8 @@ const buttonVariants = cva( variant: "default", size: "default", }, - } -) + }, +); export interface ButtonProps extends React.ButtonHTMLAttributes, diff --git a/gui/src/components/ui/switch.tsx b/gui/src/components/ui/switch.tsx index 2f5f6d74a6..3cc789fa41 100644 --- a/gui/src/components/ui/switch.tsx +++ b/gui/src/components/ui/switch.tsx @@ -9,19 +9,19 @@ const Switch = React.forwardRef< >(({ className, ...props }, ref) => ( -)) +)); Switch.displayName = SwitchPrimitives.Root.displayName export { Switch } diff --git a/gui/src/index.css b/gui/src/index.css index ff89620394..0de49a9be5 100644 --- a/gui/src/index.css +++ b/gui/src/index.css @@ -68,4 +68,59 @@ a:focus { -ms-overflow-style: none; /* IE and Edge */ scrollbar-width: none; /* Firefox */ } -} \ No newline at end of file +} + +@layer base { + :root { + /* Changes from inventory */ + --background: var(--vscode-editor-background, #002B36); + --foreground: var(--vscode-editor-foreground, #839496); + --button-background: var(--vscode-button-background, #2AA19899); + --button-foreground: var(--vscode-button-foreground, #839496); + --button-hover-background: var(--vscode-button-hoverBackground, #2AA198CC); + --input-background: var(--vscode-input-background, #003847); + --input-foreground: var(--vscode-input-foreground, #93A1A1); + --input-border: var(--vscode-input-border, #2AA19899); + --dropdown-background: var(--vscode-dropdown-background, #00212B); + --dropdown-foreground: var(--vscode-dropdown-foreground, #839496); + --list-active-selection-background: var(--vscode-list-activeSelectionBackground, #005A6F); + --list-active-selection-foreground: var(--vscode-list-activeSelectionForeground, #d6dbdb); + --list-hover-background: var(--vscode-list-hoverBackground, #004454AA); + --sidebar-background: var(--vscode-sideBar-background, #00212B); + --statusbar-background: var(--vscode-statusBar-background, #00212B); + --statusbar-foreground: var(--vscode-statusBar-foreground, #93A1A1); + --tab-active-background: var(--vscode-tab-activeBackground, #002B37); + --tab-active-foreground: var(--vscode-tab-activeForeground, #d6dbdb); + + /* Additional variables, from default taildwind adapted to VSCode PearAI Theme */ + --card: var(--vscode-editor-background, #002B36); + --card-foreground: var(--vscode-editor-foreground, #839496); + --popover: var(--vscode-editor-background, #002B36); + --popover-foreground: var(--vscode-editor-foreground, #839496); + --primary: var(--vscode-button-background, #2AA19899); + --primary-foreground: var(--vscode-button-foreground, #839496); + --secondary: var(--vscode-list-hoverBackground, #004454AA); + --secondary-foreground: var(--vscode-editor-foreground, #839496); + --muted: var(--vscode-list-hoverBackground, #004454AA); + --muted-foreground: var(--vscode-descriptionForeground, #586E75); + --accent: var(--vscode-list-hoverBackground, #004454AA); + --accent-foreground: var(--vscode-editor-foreground, #839496); + --destructive: #DC322F; + --destructive-foreground: #EEE8D5; + --border: var(--vscode-input-border, #2AA19899); + --ring: var(--vscode-focusBorder, #2AA19899); + --radius: 0.5rem; + } +} + + @layer base { + * { + /* default tailwindcss configs */ + /* @apply border-border; */ + @apply border-input; + } + body { + @apply bg-background text-foreground; + } + } + \ No newline at end of file diff --git a/gui/src/inventory/main.tsx b/gui/src/inventory/main.tsx deleted file mode 100644 index 1c84476b4a..0000000000 --- a/gui/src/inventory/main.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' -import Inventory from '../pages/inventory.js' -import './index.css' - -createRoot(document.getElementById('root')!).render( - - - , -) diff --git a/gui/src/inventory/pages/InventoryPage.tsx b/gui/src/inventory/pages/InventoryPage.tsx index 494c1b5aa5..f8554780d0 100644 --- a/gui/src/inventory/pages/InventoryPage.tsx +++ b/gui/src/inventory/pages/InventoryPage.tsx @@ -5,340 +5,345 @@ import { Switch } from "@/components/ui/switch" import { Button } from "@/components/ui/button" import { Card, CardContent } from "@/components/ui/card" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" +import { useNavigate } from "react-router-dom"; interface AITool { - id: string - name: string - description: string - icon: string - whenToUse: string - strengths: string[] - weaknesses: string[] - enabled: boolean - comingSoon?: boolean + id: string; + name: string; + description: string; + icon: string; + whenToUse: string; + strengths: string[]; + weaknesses: string[]; + enabled: boolean; + comingSoon?: boolean; } const initialTools: AITool[] = [ - { - id: "1", - name: "Search (Perplexity)", - description: - "AI-powered search engine: up-to-date information for docs, libraries, etc.", - icon: "🔍", - whenToUse: - "When you need to find information where the latest, most up-to-date version is important, e.g. documentation, software libraries, etc. Regular LLMs' knowledge are outdated by several months, so they will not be as good as Perplexity for such use cases", - strengths: [ - "Most up-to-date information", - "Non coding specific questions are also supported", - "Provides cited sources", - ], - weaknesses: [ - "May be wordy and verbose", - "Not specialized for pure code generation", - ], - enabled: true, - }, - { - id: "2", - name: "AI Chat (Continue)", - description: "AI pair programmer for flexible coding assistance", - icon: "👨‍💻", - whenToUse: - "When you need fragmented coding assistance and suggestions. Ask the chat any question, it can generate code decently well and also create files. Requires medium human intervention to apply and review changes.", - strengths: [ - "AI chat (CMD/CTRL+L and CMD/CTRL+I)", - "Context-aware suggestions", - "Code and file generation", - "Flexibility on choosing what you want to keep and discard from suggestions", - ], - weaknesses: [ - "The flexibility also means it requires at least a medium level of human intervention", - ], - enabled: true, - }, - { - id: "3", - name: "Memory (mem0)", - description: "Personalization: let the AI remember your past thoughts", - icon: "📝", - whenToUse: - "When you want the AI to remember insights from past prompts you've given it. It can automatically remember details like what version of for e.g. Python you're using, or other specific details of your codebase, like your coding styles, or your expertise level", - strengths: [ - "Intelligent memory of your coding profile", - "Increase in accuracy of results due to personalization", - ], - weaknesses: [ - "Requires you to remove expired memories manually that are no longer relevant", - "Requires PearAI server due to essential custom logic", - ], - enabled: false, - }, - { - id: "4", - name: "Creator (aider)", - description: '"No-code" assistant: complete features zero to one directly', - icon: "🤖", - whenToUse: - "When you need a feature or bug fixes investigated, or completed directly. Requires lower human intervention.", - strengths: [ - "Zero to one feature completions", - "Automated refactoring", - "Lower level of human intervention needed", - ], - weaknesses: [ - "Lower level of human intervention needed means less flexibility on what to keep and discard from suggestions", - ], - enabled: true, - }, - { - id: "5", - name: "Painter (DALL-E)", - description: "AI image generation from textual descriptions", - icon: "🎨", - whenToUse: - "Use when you need to create unique images based on text prompts", - strengths: [ - "Creative image generation", - "Wide range of styles", - "Quick results", - ], - weaknesses: [ - "May misinterpret complex prompts", - "Limited control over specific details", - ], - enabled: false, - comingSoon: true, - }, + { + id: "1", + name: "Search (Perplexity)", + description: + "AI-powered search engine: up-to-date information for docs, libraries, etc.", + icon: "🔍", + whenToUse: + "When you need to find information where the latest, most up-to-date version is important, e.g. documentation, software libraries, etc. Regular LLMs' knowledge are outdated by several months, so they will not be as good as Perplexity for such use cases", + strengths: [ + "Most up-to-date information", + "Non coding specific questions are also supported", + "Provides cited sources", + ], + weaknesses: [ + "May be wordy and verbose", + "Not specialized for pure code generation", + ], + enabled: true, + }, + { + id: "2", + name: "AI Chat (Continue)", + description: "AI pair programmer for flexible coding assistance", + icon: "👨‍💻", + whenToUse: + "When you need fragmented coding assistance and suggestions. Ask the chat any question, it can generate code decently well and also create files. Requires medium human intervention to apply and review changes.", + strengths: [ + "AI chat (CMD/CTRL+L and CMD/CTRL+I)", + "Context-aware suggestions", + "Code and file generation", + "Flexibility on choosing what you want to keep and discard from suggestions", + ], + weaknesses: [ + "The flexibility also means it requires at least a medium level of human intervention", + ], + enabled: true, + }, + { + id: "3", + name: "Memory (mem0)", + description: "Personalization: let the AI remember your past thoughts", + icon: "📝", + whenToUse: + "When you want the AI to remember insights from past prompts you've given it. It can automatically remember details like what version of for e.g. Python you're using, or other specific details of your codebase, like your coding styles, or your expertise level", + strengths: [ + "Intelligent memory of your coding profile", + "Increase in accuracy of results due to personalization", + ], + weaknesses: [ + "Requires you to remove expired memories manually that are no longer relevant", + "Requires PearAI server due to essential custom logic", + ], + enabled: false, + }, + { + id: "4", + name: "Creator (aider)", + description: '"No-code" assistant: complete features zero to one directly', + icon: "🤖", + whenToUse: + "When you need a feature or bug fixes investigated, or completed directly. Requires lower human intervention.", + strengths: [ + "Zero to one feature completions", + "Automated refactoring", + "Lower level of human intervention needed", + ], + weaknesses: [ + "Lower level of human intervention needed means less flexibility on what to keep and discard from suggestions", + ], + enabled: true, + }, + { + id: "5", + name: "Painter (DALL-E)", + description: "AI image generation from textual descriptions", + icon: "🎨", + whenToUse: + "Use when you need to create unique images based on text prompts", + strengths: [ + "Creative image generation", + "Wide range of styles", + "Quick results", + ], + weaknesses: [ + "May misinterpret complex prompts", + "Limited control over specific details", + ], + enabled: false, + comingSoon: true, + }, ]; const suggestedBuild = ["1", "2", "4"]; // IDs of suggested tools function AIToolCard({ - tool, - onClick, - onToggle, + tool, + onClick, + onToggle, }: { - tool: AITool; - onClick: () => void; - onToggle: () => void; + tool: AITool; + onClick: () => void; + onToggle: () => void; }) { - return ( - - -
-
{tool.icon}
- -
-

- {tool.name} -

-

- {tool.comingSoon ? "Coming soon" : tool.description} -

-
-
- ); + return ( + + +
+
{tool.icon}
+ +
+

+ {tool.name} +

+

+ {tool.comingSoon ? "Coming soon" : tool.description} +

+
+
+ ); } function QuickActionSlot({ - tool, - onRemove, + tool, + onRemove, }: { - tool: AITool | null; - onRemove: () => void; + tool: AITool | null; + onRemove: () => void; }) { - return ( -
- {tool ? ( - <> -
{tool.icon}
-
- {tool.name} -
- - - ) : ( -
Empty
- )} -
- ); + return ( +
+ {tool ? ( + <> +
{tool.icon}
+
+ {tool.name} +
+ + + ) : ( +
Empty
+ )} +
+ ); } export default function AIToolInventory() { - const [tools, setTools] = useState(initialTools); - const [searchQuery, setSearchQuery] = useState(""); - const [focusedTool, setFocusedTool] = useState(null); - const [quickSlots, setQuickSlots] = useState<(AITool | null)[]>([ - null, - null, - null, - null, - ]); + const [tools, setTools] = useState(initialTools); + const [searchQuery, setSearchQuery] = useState(""); + const [focusedTool, setFocusedTool] = useState(null); + const [quickSlots, setQuickSlots] = useState<(AITool | null)[]>([ + null, + null, + null, + null, + ]); + const navigate = useNavigate(); - const filteredTools = tools.filter((tool) => - tool.name.toLowerCase().includes(searchQuery.toLowerCase()), - ); + const filteredTools = tools.filter((tool) => + tool.name.toLowerCase().includes(searchQuery.toLowerCase()), + ); - const handleToggle = (id: string) => { - setTools( - tools.map((tool) => - tool.id === id ? { ...tool, enabled: !tool.enabled } : tool, - ), - ); - }; + const handleToggle = (id: string) => { + setTools( + tools.map((tool) => + tool.id === id ? { ...tool, enabled: !tool.enabled } : tool, + ), + ); + }; - const handleEquipToQuickSlot = (tool: AITool) => { - const emptySlotIndex = quickSlots.findIndex((slot) => slot === null); - if ( - emptySlotIndex !== -1 && - !quickSlots.find((slot) => slot?.id === tool.id) - ) { - const newQuickSlots = [...quickSlots]; - newQuickSlots[emptySlotIndex] = tool; - setQuickSlots(newQuickSlots); - } - }; + const handleEquipToQuickSlot = (tool: AITool) => { + const emptySlotIndex = quickSlots.findIndex((slot) => slot === null); + if ( + emptySlotIndex !== -1 && + !quickSlots.find((slot) => slot?.id === tool.id) + ) { + const newQuickSlots = [...quickSlots]; + newQuickSlots[emptySlotIndex] = tool; + setQuickSlots(newQuickSlots); + } + }; - const handleRemoveFromQuickSlot = (index: number) => { - const newQuickSlots = [...quickSlots]; - newQuickSlots[index] = null; - setQuickSlots(newQuickSlots); - }; + const handleRemoveFromQuickSlot = (index: number) => { + const newQuickSlots = [...quickSlots]; + newQuickSlots[index] = null; + setQuickSlots(newQuickSlots); + }; - return ( - -
-
-

PearAI Inventory

-
- - setSearchQuery(e.target.value)} - className="pl-10 w-full bg-input text-foreground border-input" - aria-label="Search AI tools" - /> -
-
+ return ( + +
+
+
+

PearAI Inventory

{" "} + +
+
+ + setSearchQuery(e.target.value)} + className="pl-10 w-full bg-input text-foreground border-input" + aria-label="Search AI tools" + /> +
+
-
-
-
-
- {filteredTools.map((tool) => ( - setFocusedTool(tool)} - onToggle={() => handleToggle(tool.id)} - /> - ))} -
-
-
+
+
+
+
+ {filteredTools.map((tool) => ( + setFocusedTool(tool)} + onToggle={() => handleToggle(tool.id)} + /> + ))} +
+
+
-
- {focusedTool ? ( -
-

- {focusedTool.name} {focusedTool.icon} -

-

{focusedTool.description}

-

When to use:

-

{focusedTool.whenToUse}

-

Strengths:

-
    - {focusedTool.strengths.map((strength, index) => ( -
  • {strength}
  • - ))} -
-

Weaknesses:

-
    - {focusedTool.weaknesses.map((weakness, index) => ( -
  • {weakness}
  • - ))} -
- {!focusedTool.comingSoon && ( -
- - {quickSlots.every((slot) => slot !== null) && ( -

- Quick action slots are full -

- )} -
- )} -
- ) : ( -
- Select an AI tool to view details -
- )} -
-
+
+ {focusedTool ? ( +
+

+ {focusedTool.name} {focusedTool.icon} +

+

{focusedTool.description}

+

When to use:

+

{focusedTool.whenToUse}

+

Strengths:

+
    + {focusedTool.strengths.map((strength, index) => ( +
  • {strength}
  • + ))} +
+

Weaknesses:

+
    + {focusedTool.weaknesses.map((weakness, index) => ( +
  • {weakness}
  • + ))} +
+ {!focusedTool.comingSoon && ( +
+ + {quickSlots.every((slot) => slot !== null) && ( +

+ Quick action slots are full +

+ )} +
+ )} +
+ ) : ( +
+ Select an AI tool to view details +
+ )} +
+
-
-

Quick Action Slots

-
- {quickSlots.map((slot, index) => ( - handleRemoveFromQuickSlot(index)} - /> - ))} -
-
- - Suggested Build: -
- {suggestedBuild.map((id) => { - const tool = tools.find((t) => t.id === id); - return tool ? ( - - -
- {tool.icon} - {tool.name} -
-
- -

{tool.description}

-
-
- ) : null; - })} -
-
-
-
-
- ); +
+

Quick Action Slots

+
+ {quickSlots.map((slot, index) => ( + handleRemoveFromQuickSlot(index)} + /> + ))} +
+
+ + Suggested Build: +
+ {suggestedBuild.map((id) => { + const tool = tools.find((t) => t.id === id); + return tool ? ( + + +
+ {tool.icon} + {tool.name} +
+
+ +

{tool.description}

+
+
+ ) : null; + })} +
+
+
+
+
+ ); } diff --git a/gui/src/pages/gui.tsx b/gui/src/pages/gui.tsx index 9d6a3fb8f3..7496b0ae53 100644 --- a/gui/src/pages/gui.tsx +++ b/gui/src/pages/gui.tsx @@ -413,6 +413,7 @@ function GUI() { return ( <> +
{state.history.map((item, index: number) => { @@ -498,8 +499,7 @@ function GUI() { { messageType: "userInput", data: { - input: - "Keep going.", + input: "Keep going.", }, }, "*", @@ -578,7 +578,6 @@ function GUI() { )}
- - +
{tabs.map((tab) => ( diff --git a/gui/src/vscode-webview.d.ts b/gui/src/vscode-webview.d.ts new file mode 100644 index 0000000000..623c6cee64 --- /dev/null +++ b/gui/src/vscode-webview.d.ts @@ -0,0 +1,7 @@ +declare module "vscode-webview" { + export interface WebviewApi { + postMessage(message: T): void; + getState(): T | undefined; + setState(newState: S): S; + } +} diff --git a/gui/tailwind.config.cjs b/gui/tailwind.config.cjs index a0b4840a3e..d8057a039a 100644 --- a/gui/tailwind.config.cjs +++ b/gui/tailwind.config.cjs @@ -7,11 +7,46 @@ module.exports = { "./src/*.{js,ts,jsx,tsx}", ], theme: { - extend: {}, colors: { "vsc-background": "rgb(var(--vsc-background) / )", "secondary-dark": "rgb(var(--secondary-dark) / )", }, + colors: { + background: "var(--background)", + foreground: "var(--foreground)", + button: { + DEFAULT: "var(--button-background)", + foreground: "var(--button-foreground)", + hover: "var(--button-hover-background)", + }, + input: { + DEFAULT: "var(--input-background)", + foreground: "var(--input-foreground)", + border: "var(--input-border)", + }, + dropdown: { + DEFAULT: "var(--dropdown-background)", + foreground: "var(--dropdown-foreground)", + }, + list: { + activeSelection: { + background: "var(--list-active-selection-background)", + foreground: "var(--list-active-selection-foreground)", + }, + hoverBackground: "var(--list-hover-background)", + }, + sidebar: { + background: "var(--sidebar-background)", + }, + statusbar: { + background: "var(--statusbar-background)", + foreground: "var(--statusbar-foreground)", + }, + tab: { + activeBackground: "var(--tab-active-background)", + activeForeground: "var(--tab-active-foreground)", + }, + }, }, plugins: [require("tailwindcss-animate")], corePlugins: { diff --git a/gui/tsconfig.json b/gui/tsconfig.json index 09b100dcc5..8fc034c84c 100644 --- a/gui/tsconfig.json +++ b/gui/tsconfig.json @@ -18,7 +18,8 @@ "noEmitOnError": false, "paths": { "@/*": ["./src/*"] - } + }, + "types": ["vscode-webview"] }, "include": ["src", "../src/util/messenger.ts"], "references": [{ "path": "./tsconfig.node.json" }] From 9f934defc623e822d1e8b2f7a90a4dbaa0426e83 Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Wed, 16 Oct 2024 22:57:25 -0700 Subject: [PATCH 03/18] Fixed theming and css for Inventory at last --- gui/package-lock.json | 61 +++++++++++------------ gui/package.json | 10 ++-- gui/src/components/ui/button.tsx | 2 +- gui/src/components/ui/input.tsx | 6 +-- gui/src/components/ui/switch.tsx | 4 +- gui/src/components/ui/tabs.tsx | 40 +++++++-------- gui/src/inventory/pages/InventoryPage.tsx | 19 ++++--- gui/src/pages/inventory.tsx | 4 +- gui/tailwind.config.cjs | 44 ++++++++++++++-- gui/tsconfig.json | 1 + gui/vite.config.ts | 3 +- 11 files changed, 116 insertions(+), 78 deletions(-) diff --git a/gui/package-lock.json b/gui/package-lock.json index a7fa4c6426..ca4887b728 100644 --- a/gui/package-lock.json +++ b/gui/package-lock.json @@ -63,7 +63,7 @@ "socket.io-client": "^4.7.2", "styled-components": "^5.3.6", "table": "^6.8.1", - "tailwind-merge": "^2.5.3", + "tailwind-merge": "^2.5.4", "tailwindcss-animate": "^1.0.7", "tippy.js": "^6.3.7", "unist-util-visit": "^5.0.0", @@ -75,7 +75,7 @@ "@swc/cli": "^0.3.14", "@swc/core": "^1.7.2", "@types/lodash": "^4.17.6", - "@types/node": "^20.5.6", + "@types/node": "^20.16.12", "@types/node-fetch": "^2.6.4", "@types/react": "^18.0.27", "@types/react-dom": "^18.0.10", @@ -85,13 +85,13 @@ "@types/vscode-webview": "^1.57.5", "@vitejs/plugin-react": "^4.3.2", "@vitejs/plugin-react-swc": "^3.7.0", - "autoprefixer": "^10.4.13", + "autoprefixer": "^10.4.20", "eslint": "^9.11.1", "eslint-plugin-react-hooks": "^5.1.0-rc.0", "eslint-plugin-react-refresh": "^0.4.12", "globals": "^15.9.0", - "postcss": "^8.4.21", - "tailwindcss": "^3.2.7", + "postcss": "^8.4.47", + "tailwindcss": "^3.4.14", "typescript": "^4.9.3", "typescript-eslint": "^8.7.0", "vite": "^4.1.0" @@ -13951,7 +13951,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.3.0.tgz", "integrity": "sha512-jQxj/0LKgp+j9BiTXz3O3sgs26RNet2iLWmsPyRz2SIcR4q/4SbazXfnYwbAr+vLYKSfc7qxzyGQA1HLlYiuNw==", - "license": "MIT", "peerDependencies": { "react": "^16.x || ^17.x || ^18.x" } @@ -14142,7 +14141,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", - "license": "MIT", "dependencies": { "@radix-ui/react-compose-refs": "1.1.0" }, @@ -15247,11 +15245,12 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.14.2", + "version": "20.16.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.12.tgz", + "integrity": "sha512-LfPFB0zOeCeCNQV3i+67rcoVvoN5n0NVuR2vLG0O5ySQMgchuZlC4lgz546ZOJyDtj5KIgOxy+lacOimfqZAIA==", "dev": true, - "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, "node_modules/@types/node-fetch": { @@ -15705,7 +15704,9 @@ "license": "MIT" }, "node_modules/autoprefixer": { - "version": "10.4.19", + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", "dev": true, "funding": [ { @@ -15721,13 +15722,12 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { - "browserslist": "^4.23.0", - "caniuse-lite": "^1.0.30001599", + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "postcss-value-parser": "^4.2.0" }, "bin": { @@ -16133,7 +16133,6 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz", "integrity": "sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==", - "license": "Apache-2.0", "dependencies": { "clsx": "2.0.0" }, @@ -16173,7 +16172,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", - "license": "MIT", "engines": { "node": ">=6" } @@ -18206,7 +18204,6 @@ "version": "0.452.0", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.452.0.tgz", "integrity": "sha512-kNefjOUOGm+Mu3KDiryONyPba9r+nhcrz5oJs3N6JDzGboQNEXw5GB3yB8rnV9/FA4bPyggNU6CRSihZm9MvSw==", - "license": "ISC", "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" } @@ -19329,7 +19326,9 @@ } }, "node_modules/postcss": { - "version": "8.4.38", + "version": "8.4.47", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", + "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", "funding": [ { "type": "opencollective", @@ -19344,11 +19343,10 @@ "url": "https://github.com/sponsors/ai" } ], - "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" + "picocolors": "^1.1.0", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" @@ -20889,8 +20887,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.0", - "license": "BSD-3-Clause", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "engines": { "node": ">=0.10.0" } @@ -21129,15 +21128,15 @@ "version": "2.5.4", "resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.4.tgz", "integrity": "sha512-0q8cfZHMu9nuYP/b5Shb7Y7Sh1B7Nnl5GqNr1U+n2p6+mybvRtayrQ+0042Z5byvTA8ihjlP8Odo8/VnHbZu4Q==", - "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/dcastil" } }, "node_modules/tailwindcss": { - "version": "3.4.3", - "license": "MIT", + "version": "3.4.14", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.14.tgz", + "integrity": "sha512-IcSvOcTRcUtQQ7ILQL5quRDg7Xs93PdJEk1ZLbhhvJc7uj/OAhYOnruEiwnGgBvUtaUAJ8/mhSw1o8L2jCiENA==", "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", @@ -21174,7 +21173,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/tailwindcss-animate/-/tailwindcss-animate-1.0.7.tgz", "integrity": "sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==", - "license": "MIT", "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders" } @@ -21356,9 +21354,10 @@ "license": "MIT" }, "node_modules/undici-types": { - "version": "5.26.5", - "dev": true, - "license": "MIT" + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true }, "node_modules/unified": { "version": "11.0.4", diff --git a/gui/package.json b/gui/package.json index b74f955eca..269a16b34b 100644 --- a/gui/package.json +++ b/gui/package.json @@ -66,7 +66,7 @@ "socket.io-client": "^4.7.2", "styled-components": "^5.3.6", "table": "^6.8.1", - "tailwind-merge": "^2.5.3", + "tailwind-merge": "^2.5.4", "tailwindcss-animate": "^1.0.7", "tippy.js": "^6.3.7", "unist-util-visit": "^5.0.0", @@ -78,7 +78,7 @@ "@swc/cli": "^0.3.14", "@swc/core": "^1.7.2", "@types/lodash": "^4.17.6", - "@types/node": "^20.5.6", + "@types/node": "^20.16.12", "@types/node-fetch": "^2.6.4", "@types/react": "^18.0.27", "@types/react-dom": "^18.0.10", @@ -88,13 +88,13 @@ "@types/vscode-webview": "^1.57.5", "@vitejs/plugin-react": "^4.3.2", "@vitejs/plugin-react-swc": "^3.7.0", - "autoprefixer": "^10.4.13", + "autoprefixer": "^10.4.20", "eslint": "^9.11.1", "eslint-plugin-react-hooks": "^5.1.0-rc.0", "eslint-plugin-react-refresh": "^0.4.12", "globals": "^15.9.0", - "postcss": "^8.4.21", - "tailwindcss": "^3.2.7", + "postcss": "^8.4.47", + "tailwindcss": "^3.4.14", "typescript": "^4.9.3", "typescript-eslint": "^8.7.0", "vite": "^4.1.0" diff --git a/gui/src/components/ui/button.tsx b/gui/src/components/ui/button.tsx index 2d6a57b780..e05530e624 100644 --- a/gui/src/components/ui/button.tsx +++ b/gui/src/components/ui/button.tsx @@ -5,7 +5,7 @@ import { cva, type VariantProps } from "class-variance-authority" import { cn } from "@/lib/utils" const buttonVariants = cva( - "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50", + "inline-flex items-center justify-center border-none whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50", { variants: { variant: { diff --git a/gui/src/components/ui/input.tsx b/gui/src/components/ui/input.tsx index 5af26b2c1a..21f080811b 100644 --- a/gui/src/components/ui/input.tsx +++ b/gui/src/components/ui/input.tsx @@ -11,13 +11,13 @@ const Input = React.forwardRef( - ) + ); } ) Input.displayName = "Input" diff --git a/gui/src/components/ui/switch.tsx b/gui/src/components/ui/switch.tsx index 3cc789fa41..e551132fad 100644 --- a/gui/src/components/ui/switch.tsx +++ b/gui/src/components/ui/switch.tsx @@ -9,7 +9,7 @@ const Switch = React.forwardRef< >(({ className, ...props }, ref) => ( diff --git a/gui/src/components/ui/tabs.tsx b/gui/src/components/ui/tabs.tsx index cd407bba7f..0b719ae51d 100644 --- a/gui/src/components/ui/tabs.tsx +++ b/gui/src/components/ui/tabs.tsx @@ -6,32 +6,32 @@ import { cn } from "@/lib/utils"; const Tabs = TabsPrimitive.Root; const TabsList = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); TabsList.displayName = TabsPrimitive.List.displayName; const TabsTrigger = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); TabsTrigger.displayName = TabsPrimitive.Trigger.displayName; diff --git a/gui/src/inventory/pages/InventoryPage.tsx b/gui/src/inventory/pages/InventoryPage.tsx index f8554780d0..01ce15a359 100644 --- a/gui/src/inventory/pages/InventoryPage.tsx +++ b/gui/src/inventory/pages/InventoryPage.tsx @@ -172,7 +172,7 @@ function QuickActionSlot({
+
@@ -264,7 +269,7 @@ export default function AIToolInventory() {

-
+
{focusedTool ? (

@@ -274,13 +279,13 @@ export default function AIToolInventory() {

When to use:

{focusedTool.whenToUse}

Strengths:

-
    +
      {focusedTool.strengths.map((strength, index) => (
    • {strength}
    • ))}

    Weaknesses:

    -
      +
        {focusedTool.weaknesses.map((weakness, index) => (
      • {weakness}
      • ))} @@ -288,7 +293,7 @@ export default function AIToolInventory() { {!focusedTool.comingSoon && (
        - + Suggested Build:
        {suggestedBuild.map((id) => { diff --git a/gui/src/pages/inventory.tsx b/gui/src/pages/inventory.tsx index 1dcae7756f..3b5a385f9d 100644 --- a/gui/src/pages/inventory.tsx +++ b/gui/src/pages/inventory.tsx @@ -26,9 +26,9 @@ const tabs = [ export default function Inventory() { return ( -
        +
        -
        +
        {tabs.map((tab) => ( )", @@ -46,6 +42,44 @@ module.exports = { activeBackground: "var(--tab-active-background)", activeForeground: "var(--tab-active-foreground)", }, + + /* Tailwind default configs */ + card: { + DEFAULT: "hsl(var(--card))", + foreground: "hsl(var(--card-foreground))", + }, + popover: { + DEFAULT: "hsl(var(--popover))", + foreground: "hsl(var(--popover-foreground))", + }, + primary: { + DEFAULT: "hsl(var(--primary))", + foreground: "hsl(var(--primary-foreground))", + }, + secondary: { + DEFAULT: "hsl(var(--secondary))", + foreground: "hsl(var(--secondary-foreground))", + }, + muted: { + DEFAULT: "hsl(var(--muted))", + foreground: "hsl(var(--muted-foreground))", + }, + accent: { + DEFAULT: "hsl(var(--accent))", + foreground: "hsl(var(--accent-foreground))", + }, + destructive: { + DEFAULT: "hsl(var(--destructive))", + foreground: "hsl(var(--destructive-foreground))", + }, + ring: "hsl(var(--ring))", + chart: { + 1: "hsl(var(--chart-1))", + 2: "hsl(var(--chart-2))", + 3: "hsl(var(--chart-3))", + 4: "hsl(var(--chart-4))", + 5: "hsl(var(--chart-5))", + }, }, }, plugins: [require("tailwindcss-animate")], diff --git a/gui/tsconfig.json b/gui/tsconfig.json index 8fc034c84c..dcc5a7eb53 100644 --- a/gui/tsconfig.json +++ b/gui/tsconfig.json @@ -16,6 +16,7 @@ "noEmit": true, "jsx": "react-jsx", "noEmitOnError": false, + "baseUrl": ".", "paths": { "@/*": ["./src/*"] }, diff --git a/gui/vite.config.ts b/gui/vite.config.ts index bfde22f8cc..91765cbb0f 100644 --- a/gui/vite.config.ts +++ b/gui/vite.config.ts @@ -1,11 +1,10 @@ import path from "path" import react from "@vitejs/plugin-react-swc"; -import tailwindcss from "tailwindcss"; import { defineConfig } from "vite"; // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react(), tailwindcss()], + plugins: [react()], build: { // Change the output .js filename to not include a hash rollupOptions: { From 1b1c0c5230deaf00f60a9b64774bdaa7196436aa Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Wed, 16 Oct 2024 23:06:21 -0700 Subject: [PATCH 04/18] Fix tab text color --- gui/src/components/ui/tabs.tsx | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/gui/src/components/ui/tabs.tsx b/gui/src/components/ui/tabs.tsx index 0b719ae51d..bb664fa61d 100644 --- a/gui/src/components/ui/tabs.tsx +++ b/gui/src/components/ui/tabs.tsx @@ -12,7 +12,7 @@ const TabsList = React.forwardRef< , - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )); TabsContent.displayName = TabsPrimitive.Content.displayName; From a30c62b9e5f2114891c82693c5f42b087886663d Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Thu, 17 Oct 2024 01:01:50 -0700 Subject: [PATCH 05/18] Overlay injection through PearInventoryPanel. index.css seems to be injected, but not index.js? Overlay opens with only color and nothing. --- extensions/vscode/src/extension.ts | 13 +- .../inventory/PearInventoryExtension.ts | 39 +++++ .../panels/inventory/PearInventoryPanel.ts | 163 ++++++++++++++++++ extensions/vscode/src/util/vscode.ts | 21 +++ gui/vite.config.ts | 1 + 5 files changed, 235 insertions(+), 2 deletions(-) create mode 100644 extensions/vscode/src/panels/inventory/PearInventoryExtension.ts create mode 100644 extensions/vscode/src/panels/inventory/PearInventoryPanel.ts diff --git a/extensions/vscode/src/extension.ts b/extensions/vscode/src/extension.ts index ae133cc1e0..0b54cb3622 100644 --- a/extensions/vscode/src/extension.ts +++ b/extensions/vscode/src/extension.ts @@ -8,6 +8,7 @@ import { setupCa } from "core/util/ca"; import { Telemetry } from "core/util/posthog"; import * as vscode from "vscode"; import { getExtensionVersion } from "./util/util"; +import { PearInventoryExtension } from "./panels/inventory/PearInventoryExtension"; async function dynamicImportAndActivate(context: vscode.ExtensionContext) { const { activateExtension } = await import("./activation/activate"); @@ -32,11 +33,19 @@ async function dynamicImportAndActivate(context: vscode.ExtensionContext) { } } - +let outputChannel: vscode.OutputChannel; +let extension: PearInventoryExtension; export function activate(context: vscode.ExtensionContext) { setupCa(); - return dynamicImportAndActivate(context); + dynamicImportAndActivate(context); + console.log("Activating Pear extension!!!!!"); + outputChannel = vscode.window.createOutputChannel("Pear"); + outputChannel.appendLine("Activating Pear extension!!"); + + extension = new PearInventoryExtension(context, outputChannel); + extension.activate(); + console.log("Activating!"); } export function deactivate() { diff --git a/extensions/vscode/src/panels/inventory/PearInventoryExtension.ts b/extensions/vscode/src/panels/inventory/PearInventoryExtension.ts new file mode 100644 index 0000000000..ed4410ee9f --- /dev/null +++ b/extensions/vscode/src/panels/inventory/PearInventoryExtension.ts @@ -0,0 +1,39 @@ +import * as vscode from "vscode"; +import { PearInventoryPanel } from "./PearInventoryPanel"; + +export class PearInventoryExtension { + private outputChannel: vscode.OutputChannel; + private pearInventoryPanel: PearInventoryPanel | null = null; + + constructor( + private context: vscode.ExtensionContext, + outputChannel: vscode.OutputChannel, + ) { + this.outputChannel = outputChannel; + } + + async activate() { + this.outputChannel.appendLine( + "Pear activation started11=======================", + ); + + this.pearInventoryPanel = new PearInventoryPanel( + this.context.extensionUri, + this.context, + ); + + this.context.subscriptions.push( + vscode.window.registerWebviewViewProvider( + "pearai.overlayWebview2", + this.pearInventoryPanel, + ), + ); + + this.outputChannel.appendLine("Pear Inventory extension activated!!"); + console.log("Pear Inventory extension activated!!!"); + } + // TODO: Disposal needed? + async deactivate(): Promise { + await this.pearInventoryPanel?.deactivate(); + } +} diff --git a/extensions/vscode/src/panels/inventory/PearInventoryPanel.ts b/extensions/vscode/src/panels/inventory/PearInventoryPanel.ts new file mode 100644 index 0000000000..b2f7f49749 --- /dev/null +++ b/extensions/vscode/src/panels/inventory/PearInventoryPanel.ts @@ -0,0 +1,163 @@ +import { + Webview, + window, + Uri, + ExtensionContext, + WebviewView, + WebviewViewProvider, +} from "vscode"; +import { getNonce } from "../../util/vscode"; +import { getUri } from "../../util/vscode"; + +/** + * This class manages the state and behavior of PearInventory webview panel. + * + * It contains all the data and methods for: + * + * - Creating and rendering PearInventoryPanel webview panels + * - Setting the HTML (and by proxy CSS/JavaScript) content of the webview panel + * - Setting message listeners so data can be passed between the webview and extension + */ +export class PearInventoryPanel implements WebviewViewProvider { + public static currentView: PearInventoryPanel | undefined; + private _view?: WebviewView; + public hardCoded = Uri.parse( + "Users/fryingpan/code/pearai-app/extensions/pearai-submodule", + ); + + /** + * The PearInventoryPanel class private constructor (called only from the render method). + * + * @param panel A reference to the webview panel + * @param extensionUri The URI of the directory containing the extension + */ + public constructor( + private _extensionUri: Uri, + private readonly _extensionContext: ExtensionContext, + ) { + const uriToFix = this._extensionUri.toString().split("/"); + uriToFix[-1] = "pearai-submodule/gui"; + const uriWithoutPearAiRef = uriToFix.join("/"); + this._extensionUri = Uri.parse(uriWithoutPearAiRef); + console.log(this._extensionUri); + } + + public resolveWebviewView(webviewView: WebviewView) { + console.log("Resolving WebviewView for ChatView3: ", this._extensionUri); + this._view = webviewView; + + console.log("=========================== Hard coded: ", this.hardCoded); + webviewView.webview.options = { + enableScripts: true, + localResourceRoots: [ + Uri.joinPath(this._extensionUri, "extensions/vscode/out"), + Uri.joinPath(this.hardCoded, "gui/build"), + ], + }; + + webviewView.webview.html = this._getWebviewContent( + webviewView.webview, + this.hardCoded, + ); + + this._setWebviewMessageListener(webviewView.webview); + console.log("success in resolveWebviewView!"); + } + + /** + * Defines and returns the HTML that should be rendered within the webview panel. + * + * @remarks This is also the place where references to the React webview build files + * are created and inserted into the webview HTML. + * + * @param webview A reference to the extension webview + * @param extensionUri The URI of the directory containing the extension + * @returns A template string literal containing the HTML that should be + * rendered within the webview panel + */ + private _getWebviewContent(webview: Webview, extensionUri: Uri) { + // The CSS file from the React build output + const stylesUri = getUri(webview, this.hardCoded, [ + "gui", + "build", + "assets", + "index.css", + ]); + console.log("STYLES ===================:", stylesUri); + // The JS file from the React build output + const scriptUri = getUri(webview, this.hardCoded, [ + "gui", + "build", + "assets", + "index.js", + ]); + console.log("SCRIPT ===================:", scriptUri); + + const nonce = getNonce(); + + // Tip: Install the es6-string-html VS Code extension to enable code highlighting below + return /*html*/ ` + + + + + + + + PearAI Inventory + + +
        + + + + `; + } + + /** + * Sets up an event listener to listen for messages passed from the webview context and + * executes code based on the message that is recieved. + * + * @param webview A reference to the extension webview + * @param context A reference to the extension context + */ + private _setWebviewMessageListener(webview: Webview) { + webview.onDidReceiveMessage((message: any) => { + const command = message.command; + const text = message.text; + + switch (command) { + case "saveInventory": + // Code that should run in response to the hello message command + console.log("message here!"); + window.showInformationMessage(text); + return; + // Add more switch case statements here as more webview message commands + // are created within the webview context (i.e. inside media/main.js) + } + }); + } + + public async deactivate() { + console.log("Deactivating Pear Inventory"); + } +} + +// // TODO: Disposal? +// /** +// * Cleans up and disposes of webview resources when the webview panel is closed. +// */ +// public dispose() { +// PearInventoryPanel.currentPanel = undefined; + +// // Dispose of the current webview panel +// this._panel.dispose(); + +// // Dispose of all disposables (i.e. commands) for the current webview panel +// while (this._disposables.length) { +// const disposable = this._disposables.pop(); +// if (disposable) { +// disposable.dispose(); +// } +// } +// } diff --git a/extensions/vscode/src/util/vscode.ts b/extensions/vscode/src/util/vscode.ts index 7538b7d69a..2e764c4ae0 100644 --- a/extensions/vscode/src/util/vscode.ts +++ b/extensions/vscode/src/util/vscode.ts @@ -25,6 +25,27 @@ export function getExtensionUri(): vscode.Uri { return vscode.extensions.getExtension("pearai.pearai")!.extensionUri; } +import { Uri, Webview } from "vscode"; + +/** + * A helper function which will get the webview URI of a given file or resource. + * + * @remarks This URI can be used within a webview's HTML as a link to the + * given file/resource. + * + * @param webview A reference to the extension webview + * @param extensionUri The URI of the directory containing the extension + * @param pathList An array of strings representing the path to a file/resource + * @returns A URI pointing to the file/resource + */ +export function getUri( + webview: Webview, + extensionUri: Uri, + pathList: string[], +) { + return webview.asWebviewUri(Uri.joinPath(extensionUri, ...pathList)); +} + export function getViewColumnOfFile( filepath: string, ): vscode.ViewColumn | undefined { diff --git a/gui/vite.config.ts b/gui/vite.config.ts index 91765cbb0f..a8568b141f 100644 --- a/gui/vite.config.ts +++ b/gui/vite.config.ts @@ -6,6 +6,7 @@ import { defineConfig } from "vite"; export default defineConfig({ plugins: [react()], build: { + outDir: "build", // Change the output .js filename to not include a hash rollupOptions: { // external: ["vscode-webview"], From aad1b92e38f8f00be6d4cacfb3afe06b9947fd7d Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Thu, 17 Oct 2024 01:19:39 -0700 Subject: [PATCH 06/18] using extensionUri --- .../panels/inventory/PearInventoryPanel.ts | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/extensions/vscode/src/panels/inventory/PearInventoryPanel.ts b/extensions/vscode/src/panels/inventory/PearInventoryPanel.ts index b2f7f49749..7193161653 100644 --- a/extensions/vscode/src/panels/inventory/PearInventoryPanel.ts +++ b/extensions/vscode/src/panels/inventory/PearInventoryPanel.ts @@ -35,10 +35,12 @@ export class PearInventoryPanel implements WebviewViewProvider { private _extensionUri: Uri, private readonly _extensionContext: ExtensionContext, ) { - const uriToFix = this._extensionUri.toString().split("/"); - uriToFix[-1] = "pearai-submodule/gui"; - const uriWithoutPearAiRef = uriToFix.join("/"); - this._extensionUri = Uri.parse(uriWithoutPearAiRef); + this._extensionUri = Uri.joinPath( + _extensionUri, + "..", + "pearai-submodule", + "gui", + ); console.log(this._extensionUri); } @@ -46,18 +48,18 @@ export class PearInventoryPanel implements WebviewViewProvider { console.log("Resolving WebviewView for ChatView3: ", this._extensionUri); this._view = webviewView; - console.log("=========================== Hard coded: ", this.hardCoded); + // console.log("=========================== Hard coded: ", this.hardCoded); webviewView.webview.options = { enableScripts: true, localResourceRoots: [ - Uri.joinPath(this._extensionUri, "extensions/vscode/out"), - Uri.joinPath(this.hardCoded, "gui/build"), + Uri.joinPath(this._extensionUri, "build"), + Uri.joinPath(this._extensionUri, "dist"), ], }; webviewView.webview.html = this._getWebviewContent( webviewView.webview, - this.hardCoded, + this._extensionUri, ); this._setWebviewMessageListener(webviewView.webview); @@ -77,16 +79,14 @@ export class PearInventoryPanel implements WebviewViewProvider { */ private _getWebviewContent(webview: Webview, extensionUri: Uri) { // The CSS file from the React build output - const stylesUri = getUri(webview, this.hardCoded, [ - "gui", + const stylesUri = getUri(webview, this._extensionUri, [ "build", "assets", "index.css", ]); console.log("STYLES ===================:", stylesUri); // The JS file from the React build output - const scriptUri = getUri(webview, this.hardCoded, [ - "gui", + const scriptUri = getUri(webview, this._extensionUri, [ "build", "assets", "index.js", From 19987f91dd85185f61d3e35df3ea388cb8bf6000 Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Thu, 17 Oct 2024 22:50:52 -0700 Subject: [PATCH 07/18] Either overlay or sidepart currently working. Directly resolve from existing continue webview provider instead of new panels. --- aprompts/overlay.txt | 11 ++++ .../src/ContinueGUIWebviewViewProvider.ts | 34 ++++++++-- extensions/vscode/src/extension.ts | 16 ++--- .../vscode/src/extension/VsCodeExtension.ts | 37 +++++++---- .../inventory/PearInventoryExtension.ts | 66 +++++++++---------- .../panels/inventory/PearInventoryPanel.ts | 17 ++--- gui/src/App.tsx | 3 +- gui/src/pages/onboarding/Onboarding.tsx | 2 + 8 files changed, 116 insertions(+), 70 deletions(-) create mode 100644 aprompts/overlay.txt diff --git a/aprompts/overlay.txt b/aprompts/overlay.txt new file mode 100644 index 0000000000..685ca63723 --- /dev/null +++ b/aprompts/overlay.txt @@ -0,0 +1,11 @@ + + +Context + +I'm building within a VSCode fork codebase called PearAI. Within this codebase I also have an extension integrated called pearai-submodule, and this is a fork of another codebase called Continue. + + + +Now I want to integrate an inventory feature, and an overlay modal that popups in the vscode codebase that covers most of the screen. I already have this overlay modal done, and it connects with the extension using: + +So then in @VsCodeExtension and @ContinueGUIWebviewViewProvider I resolve the pearai.overlayWebview3 name and set the html content. \ No newline at end of file diff --git a/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts b/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts index 85ee4986ed..15ad69e7bd 100644 --- a/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts +++ b/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts @@ -41,11 +41,11 @@ export class ContinueGUIWebviewViewProvider if (message.messageType === "log") { const settings = vscode.workspace.getConfiguration("pearai"); const enableDebugLogs = settings.get("enableDebugLogs", false); - + console.log("=================== HANDLE WEBVIEW MESSAGE1"); if (message.level === "debug" && !enableDebugLogs) { return; // Skip debug logs if enableDebugLogs is false } - + console.log("=================== HANDLE WEBVIEW MESSAGE2"); const timestamp = new Date().toISOString().split(".")[0]; const logMessage = `[${timestamp}] [${message.level.toUpperCase()}] ${message.text}`; this.outputChannel.appendLine(logMessage); @@ -58,9 +58,20 @@ export class ContinueGUIWebviewViewProvider _token: vscode.CancellationToken, ): void | Thenable { this._webview = webviewView.webview; - this._webview.onDidReceiveMessage((message) => - this.handleWebviewMessage(message), - ); + const extensionUri = getExtensionUri(); + console.log("=================== RESOLVING WEBVIEW IN CONTINUE PROVIDER2"); + + // this._webview.options = { + // enableScripts: true, + // localResourceRoots: [ + // vscode.Uri.joinPath(extensionUri, "out"), + // vscode.Uri.joinPath(extensionUri, "gui"), + // ], + // }; + + this._webview.onDidReceiveMessage((message) => { + return this.handleWebviewMessage(message); + }); webviewView.webview.html = this.getSidebarContent( this.extensionContext, webviewView, @@ -109,6 +120,8 @@ export class ContinueGUIWebviewViewProvider this.webviewProtocol = new VsCodeWebviewProtocol( (async () => { const configHandler = await this.configHandlerPromise; + console.log("Config handler: "); + console.log(configHandler); return configHandler.reloadConfig(); }).bind(this), ); @@ -121,6 +134,8 @@ export class ContinueGUIWebviewViewProvider edits: FileEdit[] | undefined = undefined, isFullScreen = false, ): string { + const isOverlay = panel.viewType === "pearai.overlayWebview3"; + console.log("===== Panel view type: ", panel.viewType); const extensionUri = getExtensionUri(); let scriptUri: string; let styleMainUri: string; @@ -164,7 +179,9 @@ export class ContinueGUIWebviewViewProvider if (e.affectsConfiguration("workbench.colorTheme")) { // Send new theme to GUI to update embedded Monaco themes this.webviewProtocol?.request("setTheme", { theme: getTheme() }); - this.webviewProtocol?.request("setThemeType", { themeType: getThemeType() }); + this.webviewProtocol?.request("setThemeType", { + themeType: getThemeType(), + }); } }); @@ -175,7 +192,10 @@ export class ContinueGUIWebviewViewProvider - + Continue diff --git a/extensions/vscode/src/extension.ts b/extensions/vscode/src/extension.ts index 0b54cb3622..215e25d276 100644 --- a/extensions/vscode/src/extension.ts +++ b/extensions/vscode/src/extension.ts @@ -8,7 +8,7 @@ import { setupCa } from "core/util/ca"; import { Telemetry } from "core/util/posthog"; import * as vscode from "vscode"; import { getExtensionVersion } from "./util/util"; -import { PearInventoryExtension } from "./panels/inventory/PearInventoryExtension"; +// import { PearInventoryExtension } from "./panels/inventory/PearInventoryExtension"; async function dynamicImportAndActivate(context: vscode.ExtensionContext) { const { activateExtension } = await import("./activation/activate"); @@ -34,18 +34,18 @@ async function dynamicImportAndActivate(context: vscode.ExtensionContext) { } let outputChannel: vscode.OutputChannel; -let extension: PearInventoryExtension; +// let extension: PearInventoryExtension; export function activate(context: vscode.ExtensionContext) { setupCa(); dynamicImportAndActivate(context); - console.log("Activating Pear extension!!!!!"); - outputChannel = vscode.window.createOutputChannel("Pear"); - outputChannel.appendLine("Activating Pear extension!!"); + // console.log("Activating Pear extension!!!!!"); + // outputChannel = vscode.window.createOutputChannel("Pear"); + // outputChannel.appendLine("Activating Pear extension!!"); - extension = new PearInventoryExtension(context, outputChannel); - extension.activate(); - console.log("Activating!"); + // extension = new PearInventoryExtension(context, outputChannel); + // extension.activate(); + // console.log("Activating!"); } export function deactivate() { diff --git a/extensions/vscode/src/extension/VsCodeExtension.ts b/extensions/vscode/src/extension/VsCodeExtension.ts index 56deb2a96b..b391a77cd5 100644 --- a/extensions/vscode/src/extension/VsCodeExtension.ts +++ b/extensions/vscode/src/extension/VsCodeExtension.ts @@ -83,10 +83,25 @@ export class VsCodeExtension { this.extensionContext, ); + // COMMENTING OUT SIDEBAR WILL MAKE OVERLAY WORK, + // COMMENTING OUT OVERLAY WILL MAKE SIDEBAR WORK. + // KEEPING BOTH WILL MAKE BOTH APPEAR ON UI. BUT ONLY SIDEBAR WILL HAVE FUNCTIONALITY. + // Sidebar + // context.subscriptions.push( + // vscode.window.registerWebviewViewProvider( + // "pearai.continueGUIView", + // this.sidebar, + // { + // webviewOptions: { retainContextWhenHidden: true }, + // }, + // ), + // ); + + // Register PearAI overlay context.subscriptions.push( vscode.window.registerWebviewViewProvider( - "pearai.continueGUIView", + "pearai.overlayWebview3", this.sidebar, { webviewOptions: { retainContextWhenHidden: true }, @@ -96,9 +111,7 @@ export class VsCodeExtension { resolveWebviewProtocol(this.sidebar.webviewProtocol); // Config Handler with output channel - const outputChannel = vscode.window.createOutputChannel( - "PearAI", - ); + const outputChannel = vscode.window.createOutputChannel("PearAI"); const inProcessMessenger = new InProcessMessenger< ToCoreProtocol, FromCoreProtocol @@ -249,15 +262,20 @@ export class VsCodeExtension { }); // Create a file system watcher - const watcher = vscode.workspace.createFileSystemWatcher('**/*', false, false, false); + const watcher = vscode.workspace.createFileSystemWatcher( + "**/*", + false, + false, + false, + ); // Handle file creation - watcher.onDidCreate(uri => { + watcher.onDidCreate((uri) => { this.refreshContextProviders(); }); // Handle file deletion - watcher.onDidDelete(uri => { + watcher.onDidDelete((uri) => { this.refreshContextProviders(); }); @@ -285,10 +303,7 @@ export class VsCodeExtension { } } - if ( - filepath.endsWith(".pearairc.json") || - filepath.endsWith(".prompt") - ) { + if (filepath.endsWith(".pearairc.json") || filepath.endsWith(".prompt")) { this.configHandler.reloadConfig(); } else if ( filepath.endsWith(".continueignore") || diff --git a/extensions/vscode/src/panels/inventory/PearInventoryExtension.ts b/extensions/vscode/src/panels/inventory/PearInventoryExtension.ts index ed4410ee9f..02659164dc 100644 --- a/extensions/vscode/src/panels/inventory/PearInventoryExtension.ts +++ b/extensions/vscode/src/panels/inventory/PearInventoryExtension.ts @@ -1,39 +1,39 @@ -import * as vscode from "vscode"; -import { PearInventoryPanel } from "./PearInventoryPanel"; +// import * as vscode from "vscode"; +// import { PearInventoryPanel } from "./PearInventoryPanel"; -export class PearInventoryExtension { - private outputChannel: vscode.OutputChannel; - private pearInventoryPanel: PearInventoryPanel | null = null; +// export class PearInventoryExtension { +// private outputChannel: vscode.OutputChannel; +// private pearInventoryPanel: PearInventoryPanel | null = null; - constructor( - private context: vscode.ExtensionContext, - outputChannel: vscode.OutputChannel, - ) { - this.outputChannel = outputChannel; - } +// constructor( +// private context: vscode.ExtensionContext, +// outputChannel: vscode.OutputChannel, +// ) { +// this.outputChannel = outputChannel; +// } - async activate() { - this.outputChannel.appendLine( - "Pear activation started11=======================", - ); +// async activate() { +// this.outputChannel.appendLine( +// "Pear activation started11=======================", +// ); - this.pearInventoryPanel = new PearInventoryPanel( - this.context.extensionUri, - this.context, - ); +// this.pearInventoryPanel = new PearInventoryPanel( +// this.context.extensionUri, +// this.context, +// ); - this.context.subscriptions.push( - vscode.window.registerWebviewViewProvider( - "pearai.overlayWebview2", - this.pearInventoryPanel, - ), - ); +// this.context.subscriptions.push( +// vscode.window.registerWebviewViewProvider( +// "pearai.overlayWebview2", +// this.pearInventoryPanel, +// ), +// ); - this.outputChannel.appendLine("Pear Inventory extension activated!!"); - console.log("Pear Inventory extension activated!!!"); - } - // TODO: Disposal needed? - async deactivate(): Promise { - await this.pearInventoryPanel?.deactivate(); - } -} +// this.outputChannel.appendLine("Pear Inventory extension activated!!"); +// console.log("Pear Inventory extension activated!!!"); +// } +// // TODO: Disposal needed? +// async deactivate(): Promise { +// await this.pearInventoryPanel?.deactivate(); +// } +// } diff --git a/extensions/vscode/src/panels/inventory/PearInventoryPanel.ts b/extensions/vscode/src/panels/inventory/PearInventoryPanel.ts index 7193161653..b2a77af124 100644 --- a/extensions/vscode/src/panels/inventory/PearInventoryPanel.ts +++ b/extensions/vscode/src/panels/inventory/PearInventoryPanel.ts @@ -35,13 +35,8 @@ export class PearInventoryPanel implements WebviewViewProvider { private _extensionUri: Uri, private readonly _extensionContext: ExtensionContext, ) { - this._extensionUri = Uri.joinPath( - _extensionUri, - "..", - "pearai-submodule", - "gui", - ); - console.log(this._extensionUri); + this._extensionUri = Uri.joinPath(_extensionUri, "..", "pearai-submodule"); + console.log("Extension Uri: ", this._extensionUri); } public resolveWebviewView(webviewView: WebviewView) { @@ -52,8 +47,8 @@ export class PearInventoryPanel implements WebviewViewProvider { webviewView.webview.options = { enableScripts: true, localResourceRoots: [ - Uri.joinPath(this._extensionUri, "build"), - Uri.joinPath(this._extensionUri, "dist"), + Uri.joinPath(this._extensionUri, "build", "vscode", "out"), + Uri.joinPath(this._extensionUri, "gui", "build"), ], }; @@ -80,6 +75,7 @@ export class PearInventoryPanel implements WebviewViewProvider { private _getWebviewContent(webview: Webview, extensionUri: Uri) { // The CSS file from the React build output const stylesUri = getUri(webview, this._extensionUri, [ + "gui", "build", "assets", "index.css", @@ -87,6 +83,7 @@ export class PearInventoryPanel implements WebviewViewProvider { console.log("STYLES ===================:", stylesUri); // The JS file from the React build output const scriptUri = getUri(webview, this._extensionUri, [ + "gui", "build", "assets", "index.js", @@ -102,7 +99,7 @@ export class PearInventoryPanel implements WebviewViewProvider { - + PearAI Inventory diff --git a/gui/src/App.tsx b/gui/src/App.tsx index 591a998a79..8cca6fe530 100644 --- a/gui/src/App.tsx +++ b/gui/src/App.tsx @@ -97,7 +97,8 @@ const router = createMemoryRouter([ function App() { const dispatch = useDispatch(); - + console.log("STARTING REACTJ SAPP ====================="); + console.log("Is overlay? ", (window as any).isOverlayPearAI); useSetup(dispatch); const vscTheme = useVscTheme(); diff --git a/gui/src/pages/onboarding/Onboarding.tsx b/gui/src/pages/onboarding/Onboarding.tsx index a30dc3942e..23cd5ff66d 100644 --- a/gui/src/pages/onboarding/Onboarding.tsx +++ b/gui/src/pages/onboarding/Onboarding.tsx @@ -57,6 +57,8 @@ type OnboardingMode = ToCoreFromIdeOrWebviewProtocol["completeOnboarding"][0]["mode"]; function Onboarding() { + console.log("IN ONBOARDING COMPONENT====================="); + console.log("Is overlay? ", (window as any).isOverlayPearAI); const [hovered, setHovered] = useState(-1); const navigate = useNavigate(); const dispatch = useDispatch(); From 876df5bb1dc9a2f4593dce85886835875a73569e Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Fri, 18 Oct 2024 00:08:26 -0700 Subject: [PATCH 08/18] Adding a sidebar2 temporarily so that right side bar at least loads --- extensions/vscode/package.json | 10 ++++++- .../vscode/src/extension/VsCodeExtension.ts | 26 ++++++++++++------- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index 4854b85c49..b60906cc7c 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -531,6 +531,14 @@ "name": "", "visibility": "visible" } + ], + "PearAIOverlay": [ + { + "type": "webview", + "id": "pearai.overlayWebview3", + "name": "", + "visibility": "visible" + } ] }, "jsonValidation": [ @@ -641,4 +649,4 @@ "ws": "^8.13.0", "yarn": "^1.22.21" } -} +} \ No newline at end of file diff --git a/extensions/vscode/src/extension/VsCodeExtension.ts b/extensions/vscode/src/extension/VsCodeExtension.ts index b391a77cd5..e741ce5742 100644 --- a/extensions/vscode/src/extension/VsCodeExtension.ts +++ b/extensions/vscode/src/extension/VsCodeExtension.ts @@ -41,6 +41,7 @@ export class VsCodeExtension { private ide: VsCodeIde; private tabAutocompleteModel: TabAutocompleteModel; private sidebar: ContinueGUIWebviewViewProvider; + private sidebar2: ContinueGUIWebviewViewProvider; private windowId: string; private diffManager: DiffManager; private verticalDiffManager: VerticalPerLineDiffManager; @@ -83,20 +84,26 @@ export class VsCodeExtension { this.extensionContext, ); + this.sidebar2 = new ContinueGUIWebviewViewProvider( + configHandlerPromise, + this.windowId, + this.extensionContext, + ); + // COMMENTING OUT SIDEBAR WILL MAKE OVERLAY WORK, // COMMENTING OUT OVERLAY WILL MAKE SIDEBAR WORK. // KEEPING BOTH WILL MAKE BOTH APPEAR ON UI. BUT ONLY SIDEBAR WILL HAVE FUNCTIONALITY. // Sidebar - // context.subscriptions.push( - // vscode.window.registerWebviewViewProvider( - // "pearai.continueGUIView", - // this.sidebar, - // { - // webviewOptions: { retainContextWhenHidden: true }, - // }, - // ), - // ); + context.subscriptions.push( + vscode.window.registerWebviewViewProvider( + "pearai.continueGUIView", + this.sidebar2, + { + webviewOptions: { retainContextWhenHidden: true }, + }, + ), + ); // Register PearAI overlay context.subscriptions.push( @@ -109,6 +116,7 @@ export class VsCodeExtension { ), ); resolveWebviewProtocol(this.sidebar.webviewProtocol); + resolveWebviewProtocol(this.sidebar2.webviewProtocol); // Config Handler with output channel const outputChannel = vscode.window.createOutputChannel("PearAI"); From 4c68f097dba72b8e07f39ce15914ccde95b11f12 Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Sat, 19 Oct 2024 22:00:52 -0700 Subject: [PATCH 09/18] Working chat switch by having 2 webviews --- aprompts/overlay.txt | 14 +- extensions/vscode/package.json | 12 +- .../src/ContinueGUIWebviewViewProvider.ts | 26 +- extensions/vscode/src/commands.ts | 4 + .../vscode/src/extension/VsCodeExtension.ts | 73 +++- .../inventory/PearInventoryExtension.ts | 355 ++++++++++++++++-- .../PearOverlayWebviewViewProvider.ts | 259 +++++++++++++ gui/src/pages/gui.tsx | 2 +- 8 files changed, 675 insertions(+), 70 deletions(-) create mode 100644 extensions/vscode/src/panels/inventory/PearOverlayWebviewViewProvider.ts diff --git a/aprompts/overlay.txt b/aprompts/overlay.txt index 685ca63723..ac3d1264dc 100644 --- a/aprompts/overlay.txt +++ b/aprompts/overlay.txt @@ -1,11 +1,9 @@ - - Context - I'm building within a VSCode fork codebase called PearAI. Within this codebase I also have an extension integrated called pearai-submodule, and this is a fork of another codebase called Continue. - - - -Now I want to integrate an inventory feature, and an overlay modal that popups in the vscode codebase that covers most of the screen. I already have this overlay modal done, and it connects with the extension using: - +Now I want to integrate an overlay modal that popups in the vscode codebase that covers most of the screen. I already have this overlay modal done, and it connects with the extension by resolving with this code: +```await this._webviewViewService.resolve( + "pearai.overlayWebview3", + this.webviewView!, + source.token, + );``` So then in @VsCodeExtension and @ContinueGUIWebviewViewProvider I resolve the pearai.overlayWebview3 name and set the html content. \ No newline at end of file diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index b60906cc7c..51614ce0ef 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -127,6 +127,10 @@ } }, "commands": [ + { + "command": "pearai.switchWebview", + "title": "PearAI: Switch Chat View" + }, { "command": "pearai.acceptDiff", "category": "PearAI", @@ -531,14 +535,6 @@ "name": "", "visibility": "visible" } - ], - "PearAIOverlay": [ - { - "type": "webview", - "id": "pearai.overlayWebview3", - "name": "", - "visibility": "visible" - } ] }, "jsonValidation": [ diff --git a/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts b/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts index 15ad69e7bd..3d5705f3f9 100644 --- a/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts +++ b/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts @@ -25,7 +25,7 @@ export class ContinueGUIWebviewViewProvider // Show or hide the output channel on enableDebugLogs private setupDebugLogsListener() { vscode.workspace.onDidChangeConfiguration((event) => { - if (event.affectsConfiguration('pearai.enableDebugLogs')) { + if (event.affectsConfiguration("pearai.enableDebugLogs")) { const settings = vscode.workspace.getConfiguration("pearai"); const enableDebugLogs = settings.get("enableDebugLogs", false); if (enableDebugLogs) { @@ -38,19 +38,19 @@ export class ContinueGUIWebviewViewProvider } private async handleWebviewMessage(message: any) { - if (message.messageType === "log") { - const settings = vscode.workspace.getConfiguration("pearai"); - const enableDebugLogs = settings.get("enableDebugLogs", false); - console.log("=================== HANDLE WEBVIEW MESSAGE1"); - if (message.level === "debug" && !enableDebugLogs) { - return; // Skip debug logs if enableDebugLogs is false + if (message.messageType === "log") { + const settings = vscode.workspace.getConfiguration("pearai"); + const enableDebugLogs = settings.get("enableDebugLogs", false); + + if (message.level === "debug" && !enableDebugLogs) { + return; // Skip debug logs if enableDebugLogs is false + } + + const timestamp = new Date().toISOString().split(".")[0]; + const logMessage = `[${timestamp}] [${message.level.toUpperCase()}] ${message.text}`; + this.outputChannel.appendLine(logMessage); } - console.log("=================== HANDLE WEBVIEW MESSAGE2"); - const timestamp = new Date().toISOString().split(".")[0]; - const logMessage = `[${timestamp}] [${message.level.toUpperCase()}] ${message.text}`; - this.outputChannel.appendLine(logMessage); } -} resolveWebviewView( webviewView: vscode.WebviewView, @@ -60,6 +60,7 @@ export class ContinueGUIWebviewViewProvider this._webview = webviewView.webview; const extensionUri = getExtensionUri(); console.log("=================== RESOLVING WEBVIEW IN CONTINUE PROVIDER2"); + console.log("===== Webview view type: ", webviewView.viewType); // this._webview.options = { // enableScripts: true, @@ -106,7 +107,6 @@ export class ContinueGUIWebviewViewProvider }); } - constructor( private readonly configHandlerPromise: Promise, private readonly windowId: string, diff --git a/extensions/vscode/src/commands.ts b/extensions/vscode/src/commands.ts index c9069b48a0..bc16635437 100644 --- a/extensions/vscode/src/commands.ts +++ b/extensions/vscode/src/commands.ts @@ -529,6 +529,10 @@ const commandsMap: ( "pearai.openConfigJson": () => { ide.openFile(getConfigJsonPath()); }, + "pearai.switchWebview": () => { + console.log("switch webview 2"); + vscode.commands.executeCommand("pearai.internal.switchWebview"); + }, "pearai.selectFilesAsContext": ( firstUri: vscode.Uri, uris: vscode.Uri[], diff --git a/extensions/vscode/src/extension/VsCodeExtension.ts b/extensions/vscode/src/extension/VsCodeExtension.ts index e741ce5742..3953564d07 100644 --- a/extensions/vscode/src/extension/VsCodeExtension.ts +++ b/extensions/vscode/src/extension/VsCodeExtension.ts @@ -41,7 +41,6 @@ export class VsCodeExtension { private ide: VsCodeIde; private tabAutocompleteModel: TabAutocompleteModel; private sidebar: ContinueGUIWebviewViewProvider; - private sidebar2: ContinueGUIWebviewViewProvider; private windowId: string; private diffManager: DiffManager; private verticalDiffManager: VerticalPerLineDiffManager; @@ -50,6 +49,9 @@ export class VsCodeExtension { private battery: Battery; private workOsAuthProvider: WorkOsAuthProvider; + private overlay: ContinueGUIWebviewViewProvider; + private activeWebview: "sidebar" | "overlay" = "sidebar"; + constructor(context: vscode.ExtensionContext) { // Register auth provider this.workOsAuthProvider = new WorkOsAuthProvider(context); @@ -78,45 +80,50 @@ export class VsCodeExtension { const configHandlerPromise = new Promise((resolve) => { resolveConfigHandler = resolve; }); - this.sidebar = new ContinueGUIWebviewViewProvider( - configHandlerPromise, - this.windowId, - this.extensionContext, - ); - this.sidebar2 = new ContinueGUIWebviewViewProvider( + this.sidebar = new ContinueGUIWebviewViewProvider( configHandlerPromise, this.windowId, this.extensionContext, ); - // COMMENTING OUT SIDEBAR WILL MAKE OVERLAY WORK, - // COMMENTING OUT OVERLAY WILL MAKE SIDEBAR WORK. - // KEEPING BOTH WILL MAKE BOTH APPEAR ON UI. BUT ONLY SIDEBAR WILL HAVE FUNCTIONALITY. - // Sidebar context.subscriptions.push( vscode.window.registerWebviewViewProvider( "pearai.continueGUIView", - this.sidebar2, + this.sidebar, { webviewOptions: { retainContextWhenHidden: true }, }, ), ); + resolveWebviewProtocol(this.sidebar.webviewProtocol); // Register PearAI overlay + this.overlay = new ContinueGUIWebviewViewProvider( + configHandlerPromise, + this.windowId + "_2", + this.extensionContext, + ); context.subscriptions.push( vscode.window.registerWebviewViewProvider( - "pearai.overlayWebview3", - this.sidebar, + "pearai.continueGUIView2", + this.overlay, { webviewOptions: { retainContextWhenHidden: true }, }, ), ); - resolveWebviewProtocol(this.sidebar.webviewProtocol); - resolveWebviewProtocol(this.sidebar2.webviewProtocol); + + context.subscriptions.push( + vscode.commands.registerCommand( + "pearai.internal.switchWebview", + (context: SwitchWebviewContext) => { + console.log("switch webview: ", context.state); + this.switchWebview(context); + }, + ), + ); // Config Handler with output channel const outputChannel = vscode.window.createOutputChannel("PearAI"); @@ -395,6 +402,36 @@ export class VsCodeExtension { static continueVirtualDocumentScheme = "pearai"; + public switchWebview(context: SwitchWebviewContext) { + console.log("switch webview 3"); + let activeProvider: ContinueGUIWebviewViewProvider; + if (context.state === "open") { + this.activeWebview = "overlay"; + activeProvider = this.overlay; + } else { + this.activeWebview = "sidebar"; + activeProvider = this.sidebar; + } + // this.activeWebview = + // this.activeWebview === "sidebar" ? "overlay" : "sidebar"; + // const activeProvider = + // this.activeWebview === "sidebar" ? this.sidebar : this.overlay; + + this.webviewProtocolPromise.then((protocol) => { + if (activeProvider.webview) { + protocol.webview = activeProvider.webview; + } + }); + // Refresh the webview content + activeProvider.webviewProtocol?.request("didChangeAvailableProfiles", { + profiles: [], + }); + + vscode.commands.executeCommand( + `pearai.continueGUIView${this.activeWebview === "sidebar" ? "" : "2"}.focus`, + ); + } + // eslint-disable-next-line @typescript-eslint/naming-convention private PREVIOUS_BRANCH_FOR_WORKSPACE_DIR: { [dir: string]: string } = {}; @@ -406,3 +443,7 @@ export class VsCodeExtension { this.configHandler.registerCustomContextProvider(contextProvider); } } + +type SwitchWebviewContext = { + state: "closed" | "open"; +}; \ No newline at end of file diff --git a/extensions/vscode/src/panels/inventory/PearInventoryExtension.ts b/extensions/vscode/src/panels/inventory/PearInventoryExtension.ts index 02659164dc..820a3b9ab2 100644 --- a/extensions/vscode/src/panels/inventory/PearInventoryExtension.ts +++ b/extensions/vscode/src/panels/inventory/PearInventoryExtension.ts @@ -1,39 +1,346 @@ +// // Note: This file has been modified significantly from its original contents. New commands have been added, and there has been renaming from Continue to PearAI. pearai-submodule is a fork of Continue (https://github.com/continuedev/continue). + +// import { IContextProvider } from "core"; +// import { ConfigHandler } from "core/config/ConfigHandler"; +// import { Core } from "core/core"; +// import { FromCoreProtocol, ToCoreProtocol } from "core/protocol"; +// import { InProcessMessenger } from "core/util/messenger"; +// import { getConfigJsonPath, getConfigTsPath } from "core/util/paths"; +// import fs from "fs"; +// import { v4 as uuidv4 } from "uuid"; // import * as vscode from "vscode"; -// import { PearInventoryPanel } from "./PearInventoryPanel"; + +// import { registerAllCommands } from "../../commands"; +// import { ContinueGUIWebviewViewProvider } from "../../ContinueGUIWebviewViewProvider"; +// import { DiffManager } from "../../diff/horizontal"; +// import { VerticalPerLineDiffManager } from "../../diff/verticalPerLine/manager"; +// import { VsCodeIde } from "../../ideProtocol"; +// import { registerAllCodeLensProviders } from "../../lang-server/codeLens"; +// import { setupRemoteConfigSync } from "../../stubs/activation"; +// import { +// getControlPlaneSessionInfo, +// WorkOsAuthProvider, +// } from "../../stubs/WorkOsAuthProvider"; +// import type { VsCodeWebviewProtocol } from "../../webviewProtocol"; +// import { VsCodeMessenger } from "../../extension/VsCodeMessenger"; +// import { QuickEdit } from "../../quickEdit/QuickEditQuickPick"; // export class PearInventoryExtension { -// private outputChannel: vscode.OutputChannel; -// private pearInventoryPanel: PearInventoryPanel | null = null; - -// constructor( -// private context: vscode.ExtensionContext, -// outputChannel: vscode.OutputChannel, -// ) { -// this.outputChannel = outputChannel; -// } +// // Currently some of these are public so they can be used in testing (test/test-suites) + +// private configHandler: ConfigHandler; +// private extensionContext: vscode.ExtensionContext; +// private ide: VsCodeIde; +// private sidebar: ContinueGUIWebviewViewProvider; +// private windowId: string; +// private diffManager: DiffManager; +// private verticalDiffManager: VerticalPerLineDiffManager; +// webviewProtocolPromise: Promise; +// private core: Core; +// private workOsAuthProvider: WorkOsAuthProvider; -// async activate() { -// this.outputChannel.appendLine( -// "Pear activation started11=======================", +// constructor(context: vscode.ExtensionContext) { +// // Register auth provider +// this.workOsAuthProvider = new WorkOsAuthProvider(context); +// // this.workOsAuthProvider.initialize(); +// // context.subscriptions.push(this.workOsAuthProvider); + +// let resolveWebviewProtocol: any = undefined; +// this.webviewProtocolPromise = new Promise( +// (resolve) => { +// resolveWebviewProtocol = resolve; +// }, // ); +// this.diffManager = new DiffManager(context); +// this.ide = new VsCodeIde(this.diffManager, this.webviewProtocolPromise); +// this.extensionContext = context; +// this.windowId = uuidv4(); -// this.pearInventoryPanel = new PearInventoryPanel( -// this.context.extensionUri, -// this.context, +// // Dependencies of core +// let resolveVerticalDiffManager: any = undefined; +// const verticalDiffManagerPromise = new Promise( +// (resolve) => { +// resolveVerticalDiffManager = resolve; +// }, +// ); +// let resolveConfigHandler: any = undefined; +// const configHandlerPromise = new Promise((resolve) => { +// resolveConfigHandler = resolve; +// }); +// this.sidebar = new ContinueGUIWebviewViewProvider( +// configHandlerPromise, +// this.windowId, +// this.extensionContext, // ); -// this.context.subscriptions.push( +// // Register PearAI overlay +// context.subscriptions.push( // vscode.window.registerWebviewViewProvider( -// "pearai.overlayWebview2", -// this.pearInventoryPanel, +// "pearai.overlayWebview3", +// this.sidebar, +// { +// webviewOptions: { retainContextWhenHidden: true }, +// }, +// ), +// ); +// resolveWebviewProtocol(this.sidebar.webviewProtocol); + +// // Config Handler with output channel +// const outputChannel = vscode.window.createOutputChannel("PearAI"); +// const inProcessMessenger = new InProcessMessenger< +// ToCoreProtocol, +// FromCoreProtocol +// >(); + +// new VsCodeMessenger( +// inProcessMessenger, +// this.sidebar.webviewProtocol, +// this.ide, +// verticalDiffManagerPromise, +// configHandlerPromise, +// this.workOsAuthProvider, +// ); + +// this.core = new Core(inProcessMessenger, this.ide, async (log: string) => { +// outputChannel.appendLine( +// "==========================================================================", +// ); +// outputChannel.appendLine( +// "==========================================================================", +// ); +// outputChannel.append(log); +// }); +// this.configHandler = this.core.configHandler; +// resolveConfigHandler?.(this.configHandler); + +// this.configHandler.reloadConfig(); +// this.verticalDiffManager = new VerticalPerLineDiffManager( +// this.configHandler, +// ); +// resolveVerticalDiffManager?.(this.verticalDiffManager); + +// setupRemoteConfigSync( +// this.configHandler.reloadConfig.bind(this.configHandler), +// ); + +// // handleURI +// context.subscriptions.push( +// vscode.window.registerUriHandler({ +// handleUri(uri: vscode.Uri) { +// console.log(uri); +// console.log("Received a custom URI!"); +// if (uri.authority === "pearai.pearai") { +// if (uri.path === "/ping") { +// vscode.window.showInformationMessage( +// "PearAI received a custom URI!", +// ); +// } else if (uri.path === "/auth") { +// const queryParams = new URLSearchParams(uri.query); +// const data = { +// accessToken: queryParams.get("accessToken"), +// refreshToken: queryParams.get("refreshToken"), +// }; + +// vscode.commands.executeCommand("pearai.updateUserAuth", data); +// } +// } +// }, +// }), +// ); + +// // Indexing + pause token +// // this.diffManager.webviewProtocol = this.sidebar.webviewProtocol; + +// this.configHandler.loadConfig().then((config) => { +// const { verticalDiffCodeLens } = registerAllCodeLensProviders( +// context, +// this.diffManager, +// this.verticalDiffManager.filepathToCodeLens, +// config, +// ); + +// this.verticalDiffManager.refreshCodeLens = +// verticalDiffCodeLens.refresh.bind(verticalDiffCodeLens); +// }); + +// this.configHandler.onConfigUpdate((newConfig) => { +// this.sidebar.webviewProtocol?.request("configUpdate", undefined); + +// registerAllCodeLensProviders( +// context, +// this.diffManager, +// this.verticalDiffManager.filepathToCodeLens, +// newConfig, +// ); +// }); + +// const quickEdit = new QuickEdit( +// this.verticalDiffManager, +// this.configHandler, +// this.sidebar.webviewProtocol, +// this.ide, +// context, +// ); + +// // Commands +// registerAllCommands( +// context, +// this.ide, +// context, +// this.sidebar, +// this.configHandler, +// this.diffManager, +// this.verticalDiffManager, +// this.core.continueServerClientPromise, +// null, +// quickEdit, +// this.core, +// ); + +// // Listen for file saving - use global file watcher so that changes +// // from outside the window are also caught +// fs.watchFile(getConfigJsonPath(), { interval: 1000 }, async (stats) => { +// await this.configHandler.reloadConfig(); +// }); + +// fs.watchFile(getConfigTsPath(), { interval: 1000 }, (stats) => { +// this.configHandler.reloadConfig(); +// }); + +// // Create a file system watcher +// const watcher = vscode.workspace.createFileSystemWatcher( +// "**/*", +// false, +// false, +// false, +// ); + +// // Handle file creation +// watcher.onDidCreate((uri) => { +// this.refreshContextProviders(); +// }); + +// // Handle file deletion +// watcher.onDidDelete((uri) => { +// this.refreshContextProviders(); +// }); + +// context.subscriptions.push(watcher); + +// vscode.workspace.onDidSaveTextDocument(async (event) => { +// // Listen for file changes in the workspace +// const filepath = event.uri.fsPath; + +// if (filepath === getConfigJsonPath()) { +// // Trigger a toast notification to provide UI feedback that config +// // has been updated +// const showToast = context.globalState.get( +// "showConfigUpdateToast", +// true, +// ); +// if (showToast) { +// vscode.window +// .showInformationMessage("Config updated", "Don't show again") +// .then((selection) => { +// if (selection === "Don't show again") { +// context.globalState.update("showConfigUpdateToast", false); +// } +// }); +// } +// } + +// if (filepath.endsWith(".pearairc.json") || filepath.endsWith(".prompt")) { +// this.configHandler.reloadConfig(); +// } else if ( +// filepath.endsWith(".continueignore") || +// filepath.endsWith(".gitignore") +// ) { +// // Reindex the workspaces +// this.core.invoke("index/forceReIndex", undefined); +// } else { +// // Reindex the file +// const indexer = await this.core.codebaseIndexerPromise; +// indexer.refreshFile(filepath); +// } +// }); + +// // When GitHub sign-in status changes, reload config +// vscode.authentication.onDidChangeSessions(async (e) => { +// if (e.provider.id === "github") { +// this.configHandler.reloadConfig(); +// } else if (e.provider.id === "pearai") { +// const sessionInfo = await getControlPlaneSessionInfo(true); +// this.webviewProtocolPromise.then(async (webviewProtocol) => { +// webviewProtocol.request("didChangeControlPlaneSessionInfo", { +// sessionInfo, +// }); + +// // To make sure continue-proxy models and anything else requiring it get updated access token +// this.configHandler.reloadConfig(); +// }); +// this.core.invoke("didChangeControlPlaneSessionInfo", { sessionInfo }); +// } +// }); + +// // Refresh index when branch is changed +// this.ide.getWorkspaceDirs().then((dirs) => +// dirs.forEach(async (dir) => { +// const repo = await this.ide.getRepo(vscode.Uri.file(dir)); +// if (repo) { +// repo.state.onDidChange(() => { +// // args passed to this callback are always undefined, so keep track of previous branch +// const currentBranch = repo?.state?.HEAD?.name; +// if (currentBranch) { +// if (this.PREVIOUS_BRANCH_FOR_WORKSPACE_DIR[dir]) { +// if ( +// currentBranch !== this.PREVIOUS_BRANCH_FOR_WORKSPACE_DIR[dir] +// ) { +// // Trigger refresh of index only in this directory +// this.core.invoke("index/forceReIndex", dir); +// } +// } + +// this.PREVIOUS_BRANCH_FOR_WORKSPACE_DIR[dir] = currentBranch; +// } +// }); +// } +// }), +// ); + +// // Register a content provider for the readonly virtual documents +// const documentContentProvider = new (class +// implements vscode.TextDocumentContentProvider +// { +// // emitter and its event +// onDidChangeEmitter = new vscode.EventEmitter(); +// onDidChange = this.onDidChangeEmitter.event; + +// provideTextDocumentContent(uri: vscode.Uri): string { +// return uri.query; +// } +// })(); +// context.subscriptions.push( +// vscode.workspace.registerTextDocumentContentProvider( +// PearInventoryExtension.continueVirtualDocumentScheme, +// documentContentProvider, // ), // ); -// this.outputChannel.appendLine("Pear Inventory extension activated!!"); -// console.log("Pear Inventory extension activated!!!"); +// this.ide.onDidChangeActiveTextEditor((filepath) => { +// this.core.invoke("didChangeActiveTextEditor", { filepath }); +// }); +// } + +// static continueVirtualDocumentScheme = "pearai"; + +// // eslint-disable-next-line @typescript-eslint/naming-convention +// private PREVIOUS_BRANCH_FOR_WORKSPACE_DIR: { [dir: string]: string } = {}; + +// private async refreshContextProviders() { +// this.sidebar.webviewProtocol.request("refreshSubmenuItems", undefined); // Refresh all context providers // } -// // TODO: Disposal needed? -// async deactivate(): Promise { -// await this.pearInventoryPanel?.deactivate(); + +// registerCustomContextProvider(contextProvider: IContextProvider) { +// this.configHandler.registerCustomContextProvider(contextProvider); // } // } diff --git a/extensions/vscode/src/panels/inventory/PearOverlayWebviewViewProvider.ts b/extensions/vscode/src/panels/inventory/PearOverlayWebviewViewProvider.ts new file mode 100644 index 0000000000..c4d9ccb4b5 --- /dev/null +++ b/extensions/vscode/src/panels/inventory/PearOverlayWebviewViewProvider.ts @@ -0,0 +1,259 @@ +// import type { FileEdit } from "core"; +// import { ConfigHandler } from "core/config/ConfigHandler"; +// import { getTheme, getThemeType } from "../../util/getTheme"; +// import * as vscode from "vscode"; +// import { getExtensionVersion } from "../../util/util"; +// import { getExtensionUri, getNonce, getUniqueId } from "../../util/vscode"; +// import { VsCodeWebviewProtocol } from "../../webviewProtocol"; + +// export class PearOverlayWebviewViewProvider +// implements vscode.WebviewViewProvider +// { +// public static readonly viewType = "pearai.overlayWebview3"; +// public webviewProtocol: VsCodeWebviewProtocol; + +// private updateDebugLogsStatus() { +// const settings = vscode.workspace.getConfiguration("pearai"); +// this.enableDebugLogs = settings.get("enableDebugLogs", false); +// if (this.enableDebugLogs) { +// this.outputChannel.show(true); +// } else { +// this.outputChannel.hide(); +// } +// } + +// // Show or hide the output channel on enableDebugLogs +// private setupDebugLogsListener() { +// vscode.workspace.onDidChangeConfiguration((event) => { +// if (event.affectsConfiguration("pearai.enableDebugLogs")) { +// const settings = vscode.workspace.getConfiguration("pearai"); +// const enableDebugLogs = settings.get("enableDebugLogs", false); +// if (enableDebugLogs) { +// this.outputChannel.show(true); +// } else { +// this.outputChannel.hide(); +// } +// } +// }); +// } + +// private async handleWebviewMessage(message: any) { +// if (message.messageType === "log") { +// const settings = vscode.workspace.getConfiguration("pearai"); +// const enableDebugLogs = settings.get("enableDebugLogs", false); +// console.log("=================== HANDLE PEAR WEBVIEW MESSAGE1"); +// if (message.level === "debug" && !enableDebugLogs) { +// return; // Skip debug logs if enableDebugLogs is false +// } +// console.log("=================== HANDLE PEAR WEBVIEW MESSAGE2"); +// const timestamp = new Date().toISOString().split(".")[0]; +// const logMessage = `[${timestamp}] [${message.level.toUpperCase()}] ${message.text}`; +// this.outputChannel.appendLine(logMessage); +// } +// } + +// resolveWebviewView( +// webviewView: vscode.WebviewView, +// _context: vscode.WebviewViewResolveContext, +// _token: vscode.CancellationToken, +// ): void | Thenable { +// this._webview = webviewView.webview; +// const extensionUri = getExtensionUri(); +// console.log("=================== PEAR RESOLVING WEBVIEW IN PEAR PROVIDER2"); + +// // this._webview.options = { +// // enableScripts: true, +// // localResourceRoots: [ +// // vscode.Uri.joinPath(extensionUri, "out"), +// // vscode.Uri.joinPath(extensionUri, "gui"), +// // ], +// // }; + +// this._webview.onDidReceiveMessage((message) => { +// return this.handleWebviewMessage(message); +// }); +// webviewView.webview.html = this.getSidebarContent( +// this.extensionContext, +// webviewView, +// ); +// } + +// private _webview?: vscode.Webview; +// private _webviewView?: vscode.WebviewView; +// private outputChannel: vscode.OutputChannel; +// private enableDebugLogs: boolean; + +// get isVisible() { +// return this._webviewView?.visible; +// } + +// get webview() { +// return this._webview; +// } + +// public resetWebviewProtocolWebview(): void { +// if (this._webview) { +// this.webviewProtocol.webview = this._webview; +// } else { +// console.warn("no webview found during reset"); +// } +// } + +// sendMainUserInput(input: string) { +// this.webview?.postMessage({ +// type: "userInput", +// input, +// }); +// } + +// constructor( +// private readonly configHandlerPromise: Promise, +// private readonly windowId: string, +// private readonly extensionContext: vscode.ExtensionContext, +// ) { +// this.outputChannel = vscode.window.createOutputChannel("Continue"); +// this.enableDebugLogs = false; +// this.updateDebugLogsStatus(); +// this.setupDebugLogsListener(); + +// this.webviewProtocol = new VsCodeWebviewProtocol( +// (async () => { +// const configHandler = await this.configHandlerPromise; +// console.log("Config handler: "); +// console.log(configHandler); +// return configHandler.reloadConfig(); +// }).bind(this), +// ); +// } + +// getSidebarContent( +// context: vscode.ExtensionContext | undefined, +// panel: vscode.WebviewPanel | vscode.WebviewView, +// page: string | undefined = undefined, +// edits: FileEdit[] | undefined = undefined, +// isFullScreen = false, +// ): string { +// const isOverlay = panel.viewType === "pearai.overlayWebview3"; +// console.log("===== PEAR Panel view type: ", panel.viewType); +// const extensionUri = getExtensionUri(); +// let scriptUri: string; +// let styleMainUri: string; +// const vscMediaUrl: string = panel.webview +// .asWebviewUri(vscode.Uri.joinPath(extensionUri, "gui")) +// .toString(); + +// const inDevelopmentMode = +// context?.extensionMode === vscode.ExtensionMode.Development; +// if (!inDevelopmentMode) { +// scriptUri = panel.webview +// .asWebviewUri(vscode.Uri.joinPath(extensionUri, "gui/assets/index.js")) +// .toString(); +// styleMainUri = panel.webview +// .asWebviewUri(vscode.Uri.joinPath(extensionUri, "gui/assets/index.css")) +// .toString(); +// } else { +// scriptUri = "http://localhost:5173/src/main.tsx"; +// styleMainUri = "http://localhost:5173/src/index.css"; +// } + +// panel.webview.options = { +// enableScripts: true, +// localResourceRoots: [ +// vscode.Uri.joinPath(extensionUri, "gui"), +// vscode.Uri.joinPath(extensionUri, "assets"), +// ], +// enableCommandUris: true, +// portMapping: [ +// { +// webviewPort: 65433, +// extensionHostPort: 65433, +// }, +// ], +// }; + +// const nonce = getNonce(); + +// const currentTheme = getTheme(); +// vscode.workspace.onDidChangeConfiguration((e) => { +// if (e.affectsConfiguration("workbench.colorTheme")) { +// // Send new theme to GUI to update embedded Monaco themes +// this.webviewProtocol?.request("setTheme", { theme: getTheme() }); +// this.webviewProtocol?.request("setThemeType", { +// themeType: getThemeType(), +// }); +// } +// }); + +// this.webviewProtocol.webview = panel.webview; + +// return ` +// +// +// +// +// +// + +// Continue +// +// +//
        + +// ${``} +// ${ +// inDevelopmentMode +// ? `` +// : "" +// } + +// + +// +// +// +// +// +// +// +// +// +// + +// ${ +// edits +// ? `` +// : "" +// } +// ${page ? `` : ""} +// +// `; +// } +// } diff --git a/gui/src/pages/gui.tsx b/gui/src/pages/gui.tsx index 7496b0ae53..4b11c613eb 100644 --- a/gui/src/pages/gui.tsx +++ b/gui/src/pages/gui.tsx @@ -413,7 +413,6 @@ function GUI() { return ( <> -
        {state.history.map((item, index: number) => { @@ -600,6 +599,7 @@ function GUI() { {getMetaKeyLabel()} ⌫ Cancel )} + ); } From b7495ca2e6fc0731d30859ffac134773cbe5e0bf Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Sat, 19 Oct 2024 23:10:29 -0700 Subject: [PATCH 10/18] Fix terminal bug --- extensions/vscode/package.json | 8 +++++++ .../vscode/src/extension/VsCodeExtension.ts | 21 +++++++------------ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index 51614ce0ef..824a87159d 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -535,6 +535,14 @@ "name": "", "visibility": "visible" } + ], + "PearAIOverlay": [ + { + "type": "webview", + "id": "pearai.continueGUIView2", + "name": "PearAIOverlay", + "visibility": "visible" + } ] }, "jsonValidation": [ diff --git a/extensions/vscode/src/extension/VsCodeExtension.ts b/extensions/vscode/src/extension/VsCodeExtension.ts index 3953564d07..075163a93b 100644 --- a/extensions/vscode/src/extension/VsCodeExtension.ts +++ b/extensions/vscode/src/extension/VsCodeExtension.ts @@ -403,7 +403,9 @@ export class VsCodeExtension { static continueVirtualDocumentScheme = "pearai"; public switchWebview(context: SwitchWebviewContext) { - console.log("switch webview 3"); + if (context.state === "closed" && this.activeWebview === "sidebar") { + return; + } let activeProvider: ContinueGUIWebviewViewProvider; if (context.state === "open") { this.activeWebview = "overlay"; @@ -412,26 +414,19 @@ export class VsCodeExtension { this.activeWebview = "sidebar"; activeProvider = this.sidebar; } - // this.activeWebview = - // this.activeWebview === "sidebar" ? "overlay" : "sidebar"; - // const activeProvider = - // this.activeWebview === "sidebar" ? this.sidebar : this.overlay; this.webviewProtocolPromise.then((protocol) => { if (activeProvider.webview) { protocol.webview = activeProvider.webview; } }); - // Refresh the webview content - activeProvider.webviewProtocol?.request("didChangeAvailableProfiles", { - profiles: [], - }); - vscode.commands.executeCommand( - `pearai.continueGUIView${this.activeWebview === "sidebar" ? "" : "2"}.focus`, - ); + if (activeProvider.webviewProtocol) { + activeProvider.webviewProtocol.request("didChangeAvailableProfiles", { + profiles: [], + }); + } } - // eslint-disable-next-line @typescript-eslint/naming-convention private PREVIOUS_BRANCH_FOR_WORKSPACE_DIR: { [dir: string]: string } = {}; From 246736fd4331e3d5979088e97320ce27bd447b7d Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Sun, 20 Oct 2024 15:19:54 -0700 Subject: [PATCH 11/18] Working overlay webview with multiple webview chats (on top of nang change) --- extensions/vscode/package.json | 11 +- .../src/ContinueGUIWebviewViewProvider.ts | 28 +- extensions/vscode/src/commands.ts | 4 - extensions/vscode/src/extension.ts | 11 - .../vscode/src/extension/VsCodeExtension.ts | 66 +--- .../inventory/PearInventoryExtension.ts | 346 ------------------ .../panels/inventory/PearInventoryPanel.ts | 160 -------- .../PearOverlayWebviewViewProvider.ts | 259 ------------- gui/src/App.tsx | 1 - gui/vite.config.ts | 1 - 10 files changed, 14 insertions(+), 873 deletions(-) delete mode 100644 extensions/vscode/src/panels/inventory/PearInventoryExtension.ts delete mode 100644 extensions/vscode/src/panels/inventory/PearInventoryPanel.ts delete mode 100644 extensions/vscode/src/panels/inventory/PearOverlayWebviewViewProvider.ts diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index 4640ad929a..7536363773 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -533,15 +533,8 @@ "type": "webview", "id": "pearai.pearAIChatView", "name": "", - "visibility": "visible" - } - ], - "PearAIOverlay": [ - { - "type": "webview", - "id": "pearai.continueGUIView2", - "name": "PearAIOverlay", - "visibility": "visible" + "visibility": "visible", + "title": "PearAISidebar" } ] }, diff --git a/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts b/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts index 9514825ab6..2dc40f368a 100644 --- a/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts +++ b/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts @@ -5,11 +5,13 @@ import * as vscode from "vscode"; import { getExtensionVersion } from "./util/util"; import { getExtensionUri, getNonce, getUniqueId } from "./util/vscode"; import { VsCodeWebviewProtocol } from "./webviewProtocol"; +import { PEARAI_VIEW_ID } from "./extension/VsCodeExtension"; + export class ContinueGUIWebviewViewProvider implements vscode.WebviewViewProvider { - public static readonly viewType = "pearai.pearAIChatView"; + public static readonly viewType = PEARAI_VIEW_ID; public webviewProtocol: VsCodeWebviewProtocol; private _webview?: vscode.Webview; private _webviewView?: vscode.WebviewView; @@ -62,17 +64,6 @@ export class ContinueGUIWebviewViewProvider _token: vscode.CancellationToken, ): void | Thenable { this._webview = webviewView.webview; - const extensionUri = getExtensionUri(); - console.log("=================== RESOLVING WEBVIEW IN CONTINUE PROVIDER2"); - console.log("===== Webview view type: ", webviewView.viewType); - - // this._webview.options = { - // enableScripts: true, - // localResourceRoots: [ - // vscode.Uri.joinPath(extensionUri, "out"), - // vscode.Uri.joinPath(extensionUri, "gui"), - // ], - // }; this._webview.onDidReceiveMessage((message) => { return this.handleWebviewMessage(message); @@ -83,8 +74,6 @@ export class ContinueGUIWebviewViewProvider ); } - - get isVisible() { return this._webviewView?.visible; } @@ -114,7 +103,7 @@ export class ContinueGUIWebviewViewProvider private readonly windowId: string, private readonly extensionContext: vscode.ExtensionContext, ) { - this.outputChannel = vscode.window.createOutputChannel("Continue"); + this.outputChannel = vscode.window.createOutputChannel("PearAI"); this.enableDebugLogs = false; this.updateDebugLogsStatus(); this.setupDebugLogsListener(); @@ -122,8 +111,6 @@ export class ContinueGUIWebviewViewProvider this.webviewProtocol = new VsCodeWebviewProtocol( (async () => { const configHandler = await this.configHandlerPromise; - console.log("Config handler: "); - console.log(configHandler); return configHandler.reloadConfig(); }).bind(this), ); @@ -136,8 +123,7 @@ export class ContinueGUIWebviewViewProvider edits: FileEdit[] | undefined = undefined, isFullScreen = false, ): string { - const isOverlay = panel.viewType === "pearai.overlayWebview3"; - console.log("===== Panel view type: ", panel.viewType); + const isOverlay = panel?.title === "PearAIOverlay"; // defined in pearai-app PearOverlayPart.ts const extensionUri = getExtensionUri(); let scriptUri: string; let styleMainUri: string; @@ -196,11 +182,10 @@ export class ContinueGUIWebviewViewProvider - Continue + PearAI
        @@ -249,6 +234,7 @@ export class ContinueGUIWebviewViewProvider ) || [], )} + ${ edits diff --git a/extensions/vscode/src/commands.ts b/extensions/vscode/src/commands.ts index 97bc559961..a93acb0948 100644 --- a/extensions/vscode/src/commands.ts +++ b/extensions/vscode/src/commands.ts @@ -529,10 +529,6 @@ const commandsMap: ( "pearai.openConfigJson": () => { ide.openFile(getConfigJsonPath()); }, - "pearai.switchWebview": () => { - console.log("switch webview 2"); - vscode.commands.executeCommand("pearai.internal.switchWebview"); - }, "pearai.selectFilesAsContext": ( firstUri: vscode.Uri, uris: vscode.Uri[], diff --git a/extensions/vscode/src/extension.ts b/extensions/vscode/src/extension.ts index 215e25d276..4aa42aada5 100644 --- a/extensions/vscode/src/extension.ts +++ b/extensions/vscode/src/extension.ts @@ -8,7 +8,6 @@ import { setupCa } from "core/util/ca"; import { Telemetry } from "core/util/posthog"; import * as vscode from "vscode"; import { getExtensionVersion } from "./util/util"; -// import { PearInventoryExtension } from "./panels/inventory/PearInventoryExtension"; async function dynamicImportAndActivate(context: vscode.ExtensionContext) { const { activateExtension } = await import("./activation/activate"); @@ -33,19 +32,9 @@ async function dynamicImportAndActivate(context: vscode.ExtensionContext) { } } -let outputChannel: vscode.OutputChannel; -// let extension: PearInventoryExtension; - export function activate(context: vscode.ExtensionContext) { setupCa(); dynamicImportAndActivate(context); - // console.log("Activating Pear extension!!!!!"); - // outputChannel = vscode.window.createOutputChannel("Pear"); - // outputChannel.appendLine("Activating Pear extension!!"); - - // extension = new PearInventoryExtension(context, outputChannel); - // extension.activate(); - // console.log("Activating!"); } export function deactivate() { diff --git a/extensions/vscode/src/extension/VsCodeExtension.ts b/extensions/vscode/src/extension/VsCodeExtension.ts index dbf0a8eed6..cf2a51e5d6 100644 --- a/extensions/vscode/src/extension/VsCodeExtension.ts +++ b/extensions/vscode/src/extension/VsCodeExtension.ts @@ -33,6 +33,8 @@ import { TabAutocompleteModel } from "../util/loadAutocompleteModel"; import type { VsCodeWebviewProtocol } from "../webviewProtocol"; import { VsCodeMessenger } from "./VsCodeMessenger"; +export const PEARAI_VIEW_ID = "pearai.pearAIChatView" + export class VsCodeExtension { // Currently some of these are public so they can be used in testing (test/test-suites) @@ -49,9 +51,6 @@ export class VsCodeExtension { private battery: Battery; private workOsAuthProvider: WorkOsAuthProvider; - private overlay: ContinueGUIWebviewViewProvider; - private activeWebview: "sidebar" | "overlay" = "sidebar"; - constructor(context: vscode.ExtensionContext) { // Register auth provider this.workOsAuthProvider = new WorkOsAuthProvider(context); @@ -87,10 +86,10 @@ export class VsCodeExtension { this.extensionContext, ); - // Sidebar + // Sidebar + Overlay context.subscriptions.push( vscode.window.registerWebviewViewProvider( - "pearai.pearAIChatView", + PEARAI_VIEW_ID, this.sidebar, { webviewOptions: { retainContextWhenHidden: true }, @@ -99,32 +98,6 @@ export class VsCodeExtension { ); resolveWebviewProtocol(this.sidebar.webviewProtocol); - // Register PearAI overlay - this.overlay = new ContinueGUIWebviewViewProvider( - configHandlerPromise, - this.windowId + "_2", - this.extensionContext, - ); - context.subscriptions.push( - vscode.window.registerWebviewViewProvider( - "pearai.continueGUIView2", - this.overlay, - { - webviewOptions: { retainContextWhenHidden: true }, - }, - ), - ); - - context.subscriptions.push( - vscode.commands.registerCommand( - "pearai.internal.switchWebview", - (context: SwitchWebviewContext) => { - console.log("switch webview: ", context.state); - this.switchWebview(context); - }, - ), - ); - // Config Handler with output channel const outputChannel = vscode.window.createOutputChannel("PearAI"); const inProcessMessenger = new InProcessMessenger< @@ -402,31 +375,6 @@ export class VsCodeExtension { static continueVirtualDocumentScheme = "pearai"; - public switchWebview(context: SwitchWebviewContext) { - if (context.state === "closed" && this.activeWebview === "sidebar") { - return; - } - let activeProvider: ContinueGUIWebviewViewProvider; - if (context.state === "open") { - this.activeWebview = "overlay"; - activeProvider = this.overlay; - } else { - this.activeWebview = "sidebar"; - activeProvider = this.sidebar; - } - - this.webviewProtocolPromise.then((protocol) => { - if (activeProvider.webview) { - protocol.webview = activeProvider.webview; - } - }); - - if (activeProvider.webviewProtocol) { - activeProvider.webviewProtocol.request("didChangeAvailableProfiles", { - profiles: [], - }); - } - } // eslint-disable-next-line @typescript-eslint/naming-convention private PREVIOUS_BRANCH_FOR_WORKSPACE_DIR: { [dir: string]: string } = {}; @@ -437,8 +385,4 @@ export class VsCodeExtension { registerCustomContextProvider(contextProvider: IContextProvider) { this.configHandler.registerCustomContextProvider(contextProvider); } -} - -type SwitchWebviewContext = { - state: "closed" | "open"; -}; \ No newline at end of file +} \ No newline at end of file diff --git a/extensions/vscode/src/panels/inventory/PearInventoryExtension.ts b/extensions/vscode/src/panels/inventory/PearInventoryExtension.ts deleted file mode 100644 index 820a3b9ab2..0000000000 --- a/extensions/vscode/src/panels/inventory/PearInventoryExtension.ts +++ /dev/null @@ -1,346 +0,0 @@ -// // Note: This file has been modified significantly from its original contents. New commands have been added, and there has been renaming from Continue to PearAI. pearai-submodule is a fork of Continue (https://github.com/continuedev/continue). - -// import { IContextProvider } from "core"; -// import { ConfigHandler } from "core/config/ConfigHandler"; -// import { Core } from "core/core"; -// import { FromCoreProtocol, ToCoreProtocol } from "core/protocol"; -// import { InProcessMessenger } from "core/util/messenger"; -// import { getConfigJsonPath, getConfigTsPath } from "core/util/paths"; -// import fs from "fs"; -// import { v4 as uuidv4 } from "uuid"; -// import * as vscode from "vscode"; - -// import { registerAllCommands } from "../../commands"; -// import { ContinueGUIWebviewViewProvider } from "../../ContinueGUIWebviewViewProvider"; -// import { DiffManager } from "../../diff/horizontal"; -// import { VerticalPerLineDiffManager } from "../../diff/verticalPerLine/manager"; -// import { VsCodeIde } from "../../ideProtocol"; -// import { registerAllCodeLensProviders } from "../../lang-server/codeLens"; -// import { setupRemoteConfigSync } from "../../stubs/activation"; -// import { -// getControlPlaneSessionInfo, -// WorkOsAuthProvider, -// } from "../../stubs/WorkOsAuthProvider"; -// import type { VsCodeWebviewProtocol } from "../../webviewProtocol"; -// import { VsCodeMessenger } from "../../extension/VsCodeMessenger"; -// import { QuickEdit } from "../../quickEdit/QuickEditQuickPick"; - -// export class PearInventoryExtension { -// // Currently some of these are public so they can be used in testing (test/test-suites) - -// private configHandler: ConfigHandler; -// private extensionContext: vscode.ExtensionContext; -// private ide: VsCodeIde; -// private sidebar: ContinueGUIWebviewViewProvider; -// private windowId: string; -// private diffManager: DiffManager; -// private verticalDiffManager: VerticalPerLineDiffManager; -// webviewProtocolPromise: Promise; -// private core: Core; -// private workOsAuthProvider: WorkOsAuthProvider; - -// constructor(context: vscode.ExtensionContext) { -// // Register auth provider -// this.workOsAuthProvider = new WorkOsAuthProvider(context); -// // this.workOsAuthProvider.initialize(); -// // context.subscriptions.push(this.workOsAuthProvider); - -// let resolveWebviewProtocol: any = undefined; -// this.webviewProtocolPromise = new Promise( -// (resolve) => { -// resolveWebviewProtocol = resolve; -// }, -// ); -// this.diffManager = new DiffManager(context); -// this.ide = new VsCodeIde(this.diffManager, this.webviewProtocolPromise); -// this.extensionContext = context; -// this.windowId = uuidv4(); - -// // Dependencies of core -// let resolveVerticalDiffManager: any = undefined; -// const verticalDiffManagerPromise = new Promise( -// (resolve) => { -// resolveVerticalDiffManager = resolve; -// }, -// ); -// let resolveConfigHandler: any = undefined; -// const configHandlerPromise = new Promise((resolve) => { -// resolveConfigHandler = resolve; -// }); -// this.sidebar = new ContinueGUIWebviewViewProvider( -// configHandlerPromise, -// this.windowId, -// this.extensionContext, -// ); - -// // Register PearAI overlay -// context.subscriptions.push( -// vscode.window.registerWebviewViewProvider( -// "pearai.overlayWebview3", -// this.sidebar, -// { -// webviewOptions: { retainContextWhenHidden: true }, -// }, -// ), -// ); -// resolveWebviewProtocol(this.sidebar.webviewProtocol); - -// // Config Handler with output channel -// const outputChannel = vscode.window.createOutputChannel("PearAI"); -// const inProcessMessenger = new InProcessMessenger< -// ToCoreProtocol, -// FromCoreProtocol -// >(); - -// new VsCodeMessenger( -// inProcessMessenger, -// this.sidebar.webviewProtocol, -// this.ide, -// verticalDiffManagerPromise, -// configHandlerPromise, -// this.workOsAuthProvider, -// ); - -// this.core = new Core(inProcessMessenger, this.ide, async (log: string) => { -// outputChannel.appendLine( -// "==========================================================================", -// ); -// outputChannel.appendLine( -// "==========================================================================", -// ); -// outputChannel.append(log); -// }); -// this.configHandler = this.core.configHandler; -// resolveConfigHandler?.(this.configHandler); - -// this.configHandler.reloadConfig(); -// this.verticalDiffManager = new VerticalPerLineDiffManager( -// this.configHandler, -// ); -// resolveVerticalDiffManager?.(this.verticalDiffManager); - -// setupRemoteConfigSync( -// this.configHandler.reloadConfig.bind(this.configHandler), -// ); - -// // handleURI -// context.subscriptions.push( -// vscode.window.registerUriHandler({ -// handleUri(uri: vscode.Uri) { -// console.log(uri); -// console.log("Received a custom URI!"); -// if (uri.authority === "pearai.pearai") { -// if (uri.path === "/ping") { -// vscode.window.showInformationMessage( -// "PearAI received a custom URI!", -// ); -// } else if (uri.path === "/auth") { -// const queryParams = new URLSearchParams(uri.query); -// const data = { -// accessToken: queryParams.get("accessToken"), -// refreshToken: queryParams.get("refreshToken"), -// }; - -// vscode.commands.executeCommand("pearai.updateUserAuth", data); -// } -// } -// }, -// }), -// ); - -// // Indexing + pause token -// // this.diffManager.webviewProtocol = this.sidebar.webviewProtocol; - -// this.configHandler.loadConfig().then((config) => { -// const { verticalDiffCodeLens } = registerAllCodeLensProviders( -// context, -// this.diffManager, -// this.verticalDiffManager.filepathToCodeLens, -// config, -// ); - -// this.verticalDiffManager.refreshCodeLens = -// verticalDiffCodeLens.refresh.bind(verticalDiffCodeLens); -// }); - -// this.configHandler.onConfigUpdate((newConfig) => { -// this.sidebar.webviewProtocol?.request("configUpdate", undefined); - -// registerAllCodeLensProviders( -// context, -// this.diffManager, -// this.verticalDiffManager.filepathToCodeLens, -// newConfig, -// ); -// }); - -// const quickEdit = new QuickEdit( -// this.verticalDiffManager, -// this.configHandler, -// this.sidebar.webviewProtocol, -// this.ide, -// context, -// ); - -// // Commands -// registerAllCommands( -// context, -// this.ide, -// context, -// this.sidebar, -// this.configHandler, -// this.diffManager, -// this.verticalDiffManager, -// this.core.continueServerClientPromise, -// null, -// quickEdit, -// this.core, -// ); - -// // Listen for file saving - use global file watcher so that changes -// // from outside the window are also caught -// fs.watchFile(getConfigJsonPath(), { interval: 1000 }, async (stats) => { -// await this.configHandler.reloadConfig(); -// }); - -// fs.watchFile(getConfigTsPath(), { interval: 1000 }, (stats) => { -// this.configHandler.reloadConfig(); -// }); - -// // Create a file system watcher -// const watcher = vscode.workspace.createFileSystemWatcher( -// "**/*", -// false, -// false, -// false, -// ); - -// // Handle file creation -// watcher.onDidCreate((uri) => { -// this.refreshContextProviders(); -// }); - -// // Handle file deletion -// watcher.onDidDelete((uri) => { -// this.refreshContextProviders(); -// }); - -// context.subscriptions.push(watcher); - -// vscode.workspace.onDidSaveTextDocument(async (event) => { -// // Listen for file changes in the workspace -// const filepath = event.uri.fsPath; - -// if (filepath === getConfigJsonPath()) { -// // Trigger a toast notification to provide UI feedback that config -// // has been updated -// const showToast = context.globalState.get( -// "showConfigUpdateToast", -// true, -// ); -// if (showToast) { -// vscode.window -// .showInformationMessage("Config updated", "Don't show again") -// .then((selection) => { -// if (selection === "Don't show again") { -// context.globalState.update("showConfigUpdateToast", false); -// } -// }); -// } -// } - -// if (filepath.endsWith(".pearairc.json") || filepath.endsWith(".prompt")) { -// this.configHandler.reloadConfig(); -// } else if ( -// filepath.endsWith(".continueignore") || -// filepath.endsWith(".gitignore") -// ) { -// // Reindex the workspaces -// this.core.invoke("index/forceReIndex", undefined); -// } else { -// // Reindex the file -// const indexer = await this.core.codebaseIndexerPromise; -// indexer.refreshFile(filepath); -// } -// }); - -// // When GitHub sign-in status changes, reload config -// vscode.authentication.onDidChangeSessions(async (e) => { -// if (e.provider.id === "github") { -// this.configHandler.reloadConfig(); -// } else if (e.provider.id === "pearai") { -// const sessionInfo = await getControlPlaneSessionInfo(true); -// this.webviewProtocolPromise.then(async (webviewProtocol) => { -// webviewProtocol.request("didChangeControlPlaneSessionInfo", { -// sessionInfo, -// }); - -// // To make sure continue-proxy models and anything else requiring it get updated access token -// this.configHandler.reloadConfig(); -// }); -// this.core.invoke("didChangeControlPlaneSessionInfo", { sessionInfo }); -// } -// }); - -// // Refresh index when branch is changed -// this.ide.getWorkspaceDirs().then((dirs) => -// dirs.forEach(async (dir) => { -// const repo = await this.ide.getRepo(vscode.Uri.file(dir)); -// if (repo) { -// repo.state.onDidChange(() => { -// // args passed to this callback are always undefined, so keep track of previous branch -// const currentBranch = repo?.state?.HEAD?.name; -// if (currentBranch) { -// if (this.PREVIOUS_BRANCH_FOR_WORKSPACE_DIR[dir]) { -// if ( -// currentBranch !== this.PREVIOUS_BRANCH_FOR_WORKSPACE_DIR[dir] -// ) { -// // Trigger refresh of index only in this directory -// this.core.invoke("index/forceReIndex", dir); -// } -// } - -// this.PREVIOUS_BRANCH_FOR_WORKSPACE_DIR[dir] = currentBranch; -// } -// }); -// } -// }), -// ); - -// // Register a content provider for the readonly virtual documents -// const documentContentProvider = new (class -// implements vscode.TextDocumentContentProvider -// { -// // emitter and its event -// onDidChangeEmitter = new vscode.EventEmitter(); -// onDidChange = this.onDidChangeEmitter.event; - -// provideTextDocumentContent(uri: vscode.Uri): string { -// return uri.query; -// } -// })(); -// context.subscriptions.push( -// vscode.workspace.registerTextDocumentContentProvider( -// PearInventoryExtension.continueVirtualDocumentScheme, -// documentContentProvider, -// ), -// ); - -// this.ide.onDidChangeActiveTextEditor((filepath) => { -// this.core.invoke("didChangeActiveTextEditor", { filepath }); -// }); -// } - -// static continueVirtualDocumentScheme = "pearai"; - -// // eslint-disable-next-line @typescript-eslint/naming-convention -// private PREVIOUS_BRANCH_FOR_WORKSPACE_DIR: { [dir: string]: string } = {}; - -// private async refreshContextProviders() { -// this.sidebar.webviewProtocol.request("refreshSubmenuItems", undefined); // Refresh all context providers -// } - -// registerCustomContextProvider(contextProvider: IContextProvider) { -// this.configHandler.registerCustomContextProvider(contextProvider); -// } -// } diff --git a/extensions/vscode/src/panels/inventory/PearInventoryPanel.ts b/extensions/vscode/src/panels/inventory/PearInventoryPanel.ts deleted file mode 100644 index b2a77af124..0000000000 --- a/extensions/vscode/src/panels/inventory/PearInventoryPanel.ts +++ /dev/null @@ -1,160 +0,0 @@ -import { - Webview, - window, - Uri, - ExtensionContext, - WebviewView, - WebviewViewProvider, -} from "vscode"; -import { getNonce } from "../../util/vscode"; -import { getUri } from "../../util/vscode"; - -/** - * This class manages the state and behavior of PearInventory webview panel. - * - * It contains all the data and methods for: - * - * - Creating and rendering PearInventoryPanel webview panels - * - Setting the HTML (and by proxy CSS/JavaScript) content of the webview panel - * - Setting message listeners so data can be passed between the webview and extension - */ -export class PearInventoryPanel implements WebviewViewProvider { - public static currentView: PearInventoryPanel | undefined; - private _view?: WebviewView; - public hardCoded = Uri.parse( - "Users/fryingpan/code/pearai-app/extensions/pearai-submodule", - ); - - /** - * The PearInventoryPanel class private constructor (called only from the render method). - * - * @param panel A reference to the webview panel - * @param extensionUri The URI of the directory containing the extension - */ - public constructor( - private _extensionUri: Uri, - private readonly _extensionContext: ExtensionContext, - ) { - this._extensionUri = Uri.joinPath(_extensionUri, "..", "pearai-submodule"); - console.log("Extension Uri: ", this._extensionUri); - } - - public resolveWebviewView(webviewView: WebviewView) { - console.log("Resolving WebviewView for ChatView3: ", this._extensionUri); - this._view = webviewView; - - // console.log("=========================== Hard coded: ", this.hardCoded); - webviewView.webview.options = { - enableScripts: true, - localResourceRoots: [ - Uri.joinPath(this._extensionUri, "build", "vscode", "out"), - Uri.joinPath(this._extensionUri, "gui", "build"), - ], - }; - - webviewView.webview.html = this._getWebviewContent( - webviewView.webview, - this._extensionUri, - ); - - this._setWebviewMessageListener(webviewView.webview); - console.log("success in resolveWebviewView!"); - } - - /** - * Defines and returns the HTML that should be rendered within the webview panel. - * - * @remarks This is also the place where references to the React webview build files - * are created and inserted into the webview HTML. - * - * @param webview A reference to the extension webview - * @param extensionUri The URI of the directory containing the extension - * @returns A template string literal containing the HTML that should be - * rendered within the webview panel - */ - private _getWebviewContent(webview: Webview, extensionUri: Uri) { - // The CSS file from the React build output - const stylesUri = getUri(webview, this._extensionUri, [ - "gui", - "build", - "assets", - "index.css", - ]); - console.log("STYLES ===================:", stylesUri); - // The JS file from the React build output - const scriptUri = getUri(webview, this._extensionUri, [ - "gui", - "build", - "assets", - "index.js", - ]); - console.log("SCRIPT ===================:", scriptUri); - - const nonce = getNonce(); - - // Tip: Install the es6-string-html VS Code extension to enable code highlighting below - return /*html*/ ` - - - - - - - - PearAI Inventory - - -
        - - - - `; - } - - /** - * Sets up an event listener to listen for messages passed from the webview context and - * executes code based on the message that is recieved. - * - * @param webview A reference to the extension webview - * @param context A reference to the extension context - */ - private _setWebviewMessageListener(webview: Webview) { - webview.onDidReceiveMessage((message: any) => { - const command = message.command; - const text = message.text; - - switch (command) { - case "saveInventory": - // Code that should run in response to the hello message command - console.log("message here!"); - window.showInformationMessage(text); - return; - // Add more switch case statements here as more webview message commands - // are created within the webview context (i.e. inside media/main.js) - } - }); - } - - public async deactivate() { - console.log("Deactivating Pear Inventory"); - } -} - -// // TODO: Disposal? -// /** -// * Cleans up and disposes of webview resources when the webview panel is closed. -// */ -// public dispose() { -// PearInventoryPanel.currentPanel = undefined; - -// // Dispose of the current webview panel -// this._panel.dispose(); - -// // Dispose of all disposables (i.e. commands) for the current webview panel -// while (this._disposables.length) { -// const disposable = this._disposables.pop(); -// if (disposable) { -// disposable.dispose(); -// } -// } -// } diff --git a/extensions/vscode/src/panels/inventory/PearOverlayWebviewViewProvider.ts b/extensions/vscode/src/panels/inventory/PearOverlayWebviewViewProvider.ts deleted file mode 100644 index c4d9ccb4b5..0000000000 --- a/extensions/vscode/src/panels/inventory/PearOverlayWebviewViewProvider.ts +++ /dev/null @@ -1,259 +0,0 @@ -// import type { FileEdit } from "core"; -// import { ConfigHandler } from "core/config/ConfigHandler"; -// import { getTheme, getThemeType } from "../../util/getTheme"; -// import * as vscode from "vscode"; -// import { getExtensionVersion } from "../../util/util"; -// import { getExtensionUri, getNonce, getUniqueId } from "../../util/vscode"; -// import { VsCodeWebviewProtocol } from "../../webviewProtocol"; - -// export class PearOverlayWebviewViewProvider -// implements vscode.WebviewViewProvider -// { -// public static readonly viewType = "pearai.overlayWebview3"; -// public webviewProtocol: VsCodeWebviewProtocol; - -// private updateDebugLogsStatus() { -// const settings = vscode.workspace.getConfiguration("pearai"); -// this.enableDebugLogs = settings.get("enableDebugLogs", false); -// if (this.enableDebugLogs) { -// this.outputChannel.show(true); -// } else { -// this.outputChannel.hide(); -// } -// } - -// // Show or hide the output channel on enableDebugLogs -// private setupDebugLogsListener() { -// vscode.workspace.onDidChangeConfiguration((event) => { -// if (event.affectsConfiguration("pearai.enableDebugLogs")) { -// const settings = vscode.workspace.getConfiguration("pearai"); -// const enableDebugLogs = settings.get("enableDebugLogs", false); -// if (enableDebugLogs) { -// this.outputChannel.show(true); -// } else { -// this.outputChannel.hide(); -// } -// } -// }); -// } - -// private async handleWebviewMessage(message: any) { -// if (message.messageType === "log") { -// const settings = vscode.workspace.getConfiguration("pearai"); -// const enableDebugLogs = settings.get("enableDebugLogs", false); -// console.log("=================== HANDLE PEAR WEBVIEW MESSAGE1"); -// if (message.level === "debug" && !enableDebugLogs) { -// return; // Skip debug logs if enableDebugLogs is false -// } -// console.log("=================== HANDLE PEAR WEBVIEW MESSAGE2"); -// const timestamp = new Date().toISOString().split(".")[0]; -// const logMessage = `[${timestamp}] [${message.level.toUpperCase()}] ${message.text}`; -// this.outputChannel.appendLine(logMessage); -// } -// } - -// resolveWebviewView( -// webviewView: vscode.WebviewView, -// _context: vscode.WebviewViewResolveContext, -// _token: vscode.CancellationToken, -// ): void | Thenable { -// this._webview = webviewView.webview; -// const extensionUri = getExtensionUri(); -// console.log("=================== PEAR RESOLVING WEBVIEW IN PEAR PROVIDER2"); - -// // this._webview.options = { -// // enableScripts: true, -// // localResourceRoots: [ -// // vscode.Uri.joinPath(extensionUri, "out"), -// // vscode.Uri.joinPath(extensionUri, "gui"), -// // ], -// // }; - -// this._webview.onDidReceiveMessage((message) => { -// return this.handleWebviewMessage(message); -// }); -// webviewView.webview.html = this.getSidebarContent( -// this.extensionContext, -// webviewView, -// ); -// } - -// private _webview?: vscode.Webview; -// private _webviewView?: vscode.WebviewView; -// private outputChannel: vscode.OutputChannel; -// private enableDebugLogs: boolean; - -// get isVisible() { -// return this._webviewView?.visible; -// } - -// get webview() { -// return this._webview; -// } - -// public resetWebviewProtocolWebview(): void { -// if (this._webview) { -// this.webviewProtocol.webview = this._webview; -// } else { -// console.warn("no webview found during reset"); -// } -// } - -// sendMainUserInput(input: string) { -// this.webview?.postMessage({ -// type: "userInput", -// input, -// }); -// } - -// constructor( -// private readonly configHandlerPromise: Promise, -// private readonly windowId: string, -// private readonly extensionContext: vscode.ExtensionContext, -// ) { -// this.outputChannel = vscode.window.createOutputChannel("Continue"); -// this.enableDebugLogs = false; -// this.updateDebugLogsStatus(); -// this.setupDebugLogsListener(); - -// this.webviewProtocol = new VsCodeWebviewProtocol( -// (async () => { -// const configHandler = await this.configHandlerPromise; -// console.log("Config handler: "); -// console.log(configHandler); -// return configHandler.reloadConfig(); -// }).bind(this), -// ); -// } - -// getSidebarContent( -// context: vscode.ExtensionContext | undefined, -// panel: vscode.WebviewPanel | vscode.WebviewView, -// page: string | undefined = undefined, -// edits: FileEdit[] | undefined = undefined, -// isFullScreen = false, -// ): string { -// const isOverlay = panel.viewType === "pearai.overlayWebview3"; -// console.log("===== PEAR Panel view type: ", panel.viewType); -// const extensionUri = getExtensionUri(); -// let scriptUri: string; -// let styleMainUri: string; -// const vscMediaUrl: string = panel.webview -// .asWebviewUri(vscode.Uri.joinPath(extensionUri, "gui")) -// .toString(); - -// const inDevelopmentMode = -// context?.extensionMode === vscode.ExtensionMode.Development; -// if (!inDevelopmentMode) { -// scriptUri = panel.webview -// .asWebviewUri(vscode.Uri.joinPath(extensionUri, "gui/assets/index.js")) -// .toString(); -// styleMainUri = panel.webview -// .asWebviewUri(vscode.Uri.joinPath(extensionUri, "gui/assets/index.css")) -// .toString(); -// } else { -// scriptUri = "http://localhost:5173/src/main.tsx"; -// styleMainUri = "http://localhost:5173/src/index.css"; -// } - -// panel.webview.options = { -// enableScripts: true, -// localResourceRoots: [ -// vscode.Uri.joinPath(extensionUri, "gui"), -// vscode.Uri.joinPath(extensionUri, "assets"), -// ], -// enableCommandUris: true, -// portMapping: [ -// { -// webviewPort: 65433, -// extensionHostPort: 65433, -// }, -// ], -// }; - -// const nonce = getNonce(); - -// const currentTheme = getTheme(); -// vscode.workspace.onDidChangeConfiguration((e) => { -// if (e.affectsConfiguration("workbench.colorTheme")) { -// // Send new theme to GUI to update embedded Monaco themes -// this.webviewProtocol?.request("setTheme", { theme: getTheme() }); -// this.webviewProtocol?.request("setThemeType", { -// themeType: getThemeType(), -// }); -// } -// }); - -// this.webviewProtocol.webview = panel.webview; - -// return ` -// -// -// -// -// -// - -// Continue -// -// -//
        - -// ${``} -// ${ -// inDevelopmentMode -// ? `` -// : "" -// } - -// - -// -// -// -// -// -// -// -// -// -// - -// ${ -// edits -// ? `` -// : "" -// } -// ${page ? `` : ""} -// -// `; -// } -// } diff --git a/gui/src/App.tsx b/gui/src/App.tsx index 8cca6fe530..e8959f5988 100644 --- a/gui/src/App.tsx +++ b/gui/src/App.tsx @@ -97,7 +97,6 @@ const router = createMemoryRouter([ function App() { const dispatch = useDispatch(); - console.log("STARTING REACTJ SAPP ====================="); console.log("Is overlay? ", (window as any).isOverlayPearAI); useSetup(dispatch); diff --git a/gui/vite.config.ts b/gui/vite.config.ts index a8568b141f..91765cbb0f 100644 --- a/gui/vite.config.ts +++ b/gui/vite.config.ts @@ -6,7 +6,6 @@ import { defineConfig } from "vite"; export default defineConfig({ plugins: [react()], build: { - outDir: "build", // Change the output .js filename to not include a hash rollupOptions: { // external: ["vscode-webview"], From 5f4708504d3ab41838cbc7976d78597fbf0b3666 Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Sun, 20 Oct 2024 15:23:38 -0700 Subject: [PATCH 12/18] remove prompt --- aprompts/overlay.txt | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 aprompts/overlay.txt diff --git a/aprompts/overlay.txt b/aprompts/overlay.txt deleted file mode 100644 index ac3d1264dc..0000000000 --- a/aprompts/overlay.txt +++ /dev/null @@ -1,9 +0,0 @@ -Context -I'm building within a VSCode fork codebase called PearAI. Within this codebase I also have an extension integrated called pearai-submodule, and this is a fork of another codebase called Continue. -Now I want to integrate an overlay modal that popups in the vscode codebase that covers most of the screen. I already have this overlay modal done, and it connects with the extension by resolving with this code: -```await this._webviewViewService.resolve( - "pearai.overlayWebview3", - this.webviewView!, - source.token, - );``` -So then in @VsCodeExtension and @ContinueGUIWebviewViewProvider I resolve the pearai.overlayWebview3 name and set the html content. \ No newline at end of file From ce6101ab18f7301b6a05005d2bffccbf32e4d14d Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Sun, 20 Oct 2024 15:27:38 -0700 Subject: [PATCH 13/18] Remove vscode utility --- gui/src/inventory/utilities/vscode.ts | 79 --------------------------- 1 file changed, 79 deletions(-) delete mode 100644 gui/src/inventory/utilities/vscode.ts diff --git a/gui/src/inventory/utilities/vscode.ts b/gui/src/inventory/utilities/vscode.ts deleted file mode 100644 index 3423758015..0000000000 --- a/gui/src/inventory/utilities/vscode.ts +++ /dev/null @@ -1,79 +0,0 @@ -import type { WebviewApi } from "vscode-webview"; - -const PEAR_AI_STATE_KEY = "PearAIStateKey" -/** - * A utility wrapper around the acquireVsCodeApi() function, which enables - * message passing and state management between the webview and extension - * contexts. - * - * This utility also enables webview code to be run in a web browser-based - * dev server by using native web browser features that mock the functionality - * enabled by acquireVsCodeApi. - */ -class VSCodeAPIWrapper { - private readonly vsCodeApi: WebviewApi | undefined; - - constructor() { - // Check if the acquireVsCodeApi function exists in the current development - // context (i.e. VS Code development window or web browser) - if (typeof acquireVsCodeApi === "function") { - this.vsCodeApi = acquireVsCodeApi(); - } - } - - /** - * Post a message (i.e. send arbitrary data) to the owner of the webview. - * - * @remarks When running webview code inside a web browser, postMessage will instead - * log the given message to the console. - * - * @param message Abitrary data (must be JSON serializable) to send to the extension context. - */ - public postMessage(message: unknown) { - if (this.vsCodeApi) { - this.vsCodeApi.postMessage(message); - } else { - console.log(message); - } - } - - /** - * Get the persistent state stored for this webview. - * - * @remarks When running webview source code inside a web browser, getState will retrieve state - * from local storage (https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage). - * - * @return The current state or `undefined` if no state has been set. - */ - public getState(): unknown | undefined { - if (this.vsCodeApi) { - return this.vsCodeApi.getState(); - } else { - const state = localStorage.getItem(PEAR_AI_STATE_KEY); - return state ? JSON.parse(state) : undefined; - } - } - - /** - * Set the persistent state stored for this webview. - * - * @remarks When running webview source code inside a web browser, setState will set the given - * state using local storage (https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage). - * - * @param newState New persisted state. This must be a JSON serializable object. Can be retrieved - * using {@link getState}. - * - * @return The new state. - */ - public setState(newState: T): T { - if (this.vsCodeApi) { - return this.vsCodeApi.setState(newState); - } else { - localStorage.setItem(PEAR_AI_STATE_KEY, JSON.stringify(newState)); - return newState; - } - } -} - -// Exports class singleton to prevent multiple invocations of acquireVsCodeApi. -export const vscode = new VSCodeAPIWrapper(); \ No newline at end of file From 70190ca337001cf86bce766ddfe6c21edffe30aa Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Sun, 20 Oct 2024 15:29:38 -0700 Subject: [PATCH 14/18] Remove useless file and logs --- gui/src/pages/onboarding/Onboarding.tsx | 2 -- gui/src/vscode-webview.d.ts | 7 ------- 2 files changed, 9 deletions(-) delete mode 100644 gui/src/vscode-webview.d.ts diff --git a/gui/src/pages/onboarding/Onboarding.tsx b/gui/src/pages/onboarding/Onboarding.tsx index 23cd5ff66d..a30dc3942e 100644 --- a/gui/src/pages/onboarding/Onboarding.tsx +++ b/gui/src/pages/onboarding/Onboarding.tsx @@ -57,8 +57,6 @@ type OnboardingMode = ToCoreFromIdeOrWebviewProtocol["completeOnboarding"][0]["mode"]; function Onboarding() { - console.log("IN ONBOARDING COMPONENT====================="); - console.log("Is overlay? ", (window as any).isOverlayPearAI); const [hovered, setHovered] = useState(-1); const navigate = useNavigate(); const dispatch = useDispatch(); diff --git a/gui/src/vscode-webview.d.ts b/gui/src/vscode-webview.d.ts deleted file mode 100644 index 623c6cee64..0000000000 --- a/gui/src/vscode-webview.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -declare module "vscode-webview" { - export interface WebviewApi { - postMessage(message: T): void; - getState(): T | undefined; - setState(newState: S): S; - } -} From 898a3d607cac151602a5ef360c046f692f215e2f Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Sun, 20 Oct 2024 15:31:52 -0700 Subject: [PATCH 15/18] Cleanup --- extensions/vscode/package.json | 4 ---- extensions/vscode/src/util/vscode.ts | 21 --------------------- 2 files changed, 25 deletions(-) diff --git a/extensions/vscode/package.json b/extensions/vscode/package.json index 7536363773..fc5ae3c836 100644 --- a/extensions/vscode/package.json +++ b/extensions/vscode/package.json @@ -127,10 +127,6 @@ } }, "commands": [ - { - "command": "pearai.switchWebview", - "title": "PearAI: Switch Chat View" - }, { "command": "pearai.acceptDiff", "category": "PearAI", diff --git a/extensions/vscode/src/util/vscode.ts b/extensions/vscode/src/util/vscode.ts index 2e764c4ae0..7538b7d69a 100644 --- a/extensions/vscode/src/util/vscode.ts +++ b/extensions/vscode/src/util/vscode.ts @@ -25,27 +25,6 @@ export function getExtensionUri(): vscode.Uri { return vscode.extensions.getExtension("pearai.pearai")!.extensionUri; } -import { Uri, Webview } from "vscode"; - -/** - * A helper function which will get the webview URI of a given file or resource. - * - * @remarks This URI can be used within a webview's HTML as a link to the - * given file/resource. - * - * @param webview A reference to the extension webview - * @param extensionUri The URI of the directory containing the extension - * @param pathList An array of strings representing the path to a file/resource - * @returns A URI pointing to the file/resource - */ -export function getUri( - webview: Webview, - extensionUri: Uri, - pathList: string[], -) { - return webview.asWebviewUri(Uri.joinPath(extensionUri, ...pathList)); -} - export function getViewColumnOfFile( filepath: string, ): vscode.ViewColumn | undefined { From 06309e01947ea430737db79519ff9801aa4bcd85 Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Sun, 20 Oct 2024 15:43:16 -0700 Subject: [PATCH 16/18] chat view id --- extensions/vscode/src/ContinueGUIWebviewViewProvider.ts | 4 ++-- extensions/vscode/src/extension/VsCodeExtension.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts b/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts index 2dc40f368a..f8dccfd82b 100644 --- a/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts +++ b/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts @@ -5,13 +5,13 @@ import * as vscode from "vscode"; import { getExtensionVersion } from "./util/util"; import { getExtensionUri, getNonce, getUniqueId } from "./util/vscode"; import { VsCodeWebviewProtocol } from "./webviewProtocol"; -import { PEARAI_VIEW_ID } from "./extension/VsCodeExtension"; +import { PEARAI_CHAT_VIEW_ID } from "./extension/VsCodeExtension"; export class ContinueGUIWebviewViewProvider implements vscode.WebviewViewProvider { - public static readonly viewType = PEARAI_VIEW_ID; + public static readonly viewType = PEARAI_CHAT_VIEW_ID; public webviewProtocol: VsCodeWebviewProtocol; private _webview?: vscode.Webview; private _webviewView?: vscode.WebviewView; diff --git a/extensions/vscode/src/extension/VsCodeExtension.ts b/extensions/vscode/src/extension/VsCodeExtension.ts index cf2a51e5d6..b168a03495 100644 --- a/extensions/vscode/src/extension/VsCodeExtension.ts +++ b/extensions/vscode/src/extension/VsCodeExtension.ts @@ -33,7 +33,7 @@ import { TabAutocompleteModel } from "../util/loadAutocompleteModel"; import type { VsCodeWebviewProtocol } from "../webviewProtocol"; import { VsCodeMessenger } from "./VsCodeMessenger"; -export const PEARAI_VIEW_ID = "pearai.pearAIChatView" +export const PEARAI_CHAT_VIEW_ID = "pearai.pearAIChatView" export class VsCodeExtension { // Currently some of these are public so they can be used in testing (test/test-suites) @@ -89,7 +89,7 @@ export class VsCodeExtension { // Sidebar + Overlay context.subscriptions.push( vscode.window.registerWebviewViewProvider( - PEARAI_VIEW_ID, + PEARAI_CHAT_VIEW_ID, this.sidebar, { webviewOptions: { retainContextWhenHidden: true }, From 84eba2503f8680210b87384690d1dcf6f291059b Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Sun, 20 Oct 2024 16:44:04 -0700 Subject: [PATCH 17/18] added unique identifier for overlay webview --- extensions/vscode/src/ContinueGUIWebviewViewProvider.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts b/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts index f8dccfd82b..74cbfbe978 100644 --- a/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts +++ b/extensions/vscode/src/ContinueGUIWebviewViewProvider.ts @@ -173,7 +173,9 @@ export class ContinueGUIWebviewViewProvider } }); - this.webviewProtocol.addWebview(panel.viewType, panel.webview); + // weview / panel's PearAIOverlay title is defined in pearai-app's PearOverlayParts.ts + // A unique identifier is needed for protocol to distinguish the webviews. + this.webviewProtocol.addWebview(panel?.title === "PearAIOverlay" ? panel.title : panel.viewType, panel.webview); return ` From cdd530aa61ea30281571081f3e69d16b810b8692 Mon Sep 17 00:00:00 2001 From: Duke Pan Date: Sun, 20 Oct 2024 19:30:19 -0700 Subject: [PATCH 18/18] Working overlay chat simultaneous with other chats + fixed some UI for inventory --- gui/src/components/ui/badge.tsx | 36 +++++++++++++++++++++++ gui/src/inventory/pages/InventoryPage.tsx | 2 ++ gui/src/pages/gui.tsx | 9 +++++- gui/src/pages/inventory.tsx | 2 +- 4 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 gui/src/components/ui/badge.tsx diff --git a/gui/src/components/ui/badge.tsx b/gui/src/components/ui/badge.tsx new file mode 100644 index 0000000000..e87d62bf1a --- /dev/null +++ b/gui/src/components/ui/badge.tsx @@ -0,0 +1,36 @@ +import * as React from "react" +import { cva, type VariantProps } from "class-variance-authority" + +import { cn } from "@/lib/utils" + +const badgeVariants = cva( + "inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: + "border-transparent bg-primary text-primary-foreground shadow hover:bg-primary/80", + secondary: + "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground shadow hover:bg-destructive/80", + outline: "text-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + } +) + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return ( +
        + ) +} + +export { Badge, badgeVariants } diff --git a/gui/src/inventory/pages/InventoryPage.tsx b/gui/src/inventory/pages/InventoryPage.tsx index 01ce15a359..db236b0d32 100644 --- a/gui/src/inventory/pages/InventoryPage.tsx +++ b/gui/src/inventory/pages/InventoryPage.tsx @@ -6,6 +6,7 @@ import { Button } from "@/components/ui/button" import { Card, CardContent } from "@/components/ui/card" import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip" import { useNavigate } from "react-router-dom"; +import { Badge } from '@/components/ui/badge' interface AITool { id: string; @@ -233,6 +234,7 @@ export default function AIToolInventory() {

        PearAI Inventory

        {" "} + Beta
        ) : null} + { + navigate("/inventory"); + }} + className="mr-auto" + > + PearAI Inventory + {" "} {!!showTutorialCard && (
        @@ -599,7 +607,6 @@ function GUI() { {getMetaKeyLabel()} ⌫ Cancel )} - ); } diff --git a/gui/src/pages/inventory.tsx b/gui/src/pages/inventory.tsx index 3b5a385f9d..b8c44fd329 100644 --- a/gui/src/pages/inventory.tsx +++ b/gui/src/pages/inventory.tsx @@ -26,7 +26,7 @@ const tabs = [ export default function Inventory() { return ( -
        +