diff --git a/CHANGELOG.md b/CHANGELOG.md index 5425f6ac..34736ee2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## [0.17.0](https://github.com/stacklok/codegate-ui/compare/v0.16.0...v0.17.0) (2025-02-20) + + +### Features + +* add workspaces impacted by provider deletion ([#340](https://github.com/stacklok/codegate-ui/issues/340)) ([5c0544f](https://github.com/stacklok/codegate-ui/commit/5c0544f57fadc742fe160ee6f359cc5da5f8337e)) +* strip markdown in messages table ([#336](https://github.com/stacklok/codegate-ui/issues/336)) ([2f8ab95](https://github.com/stacklok/codegate-ui/commit/2f8ab953590deca22271604b0400b7c5c19c40be)) +* support PII on the dashboard ([#326](https://github.com/stacklok/codegate-ui/issues/326)) ([279fe57](https://github.com/stacklok/codegate-ui/commit/279fe57f68994466c8b1f94c227dadb177e56c77)) + + +### Bug Fixes + +* audit vuln deps ([#332](https://github.com/stacklok/codegate-ui/issues/332)) ([73c55a2](https://github.com/stacklok/codegate-ui/commit/73c55a2b3cf763c7b78747836c551f41dc8dfda5)) +* inline code word wrap ([#335](https://github.com/stacklok/codegate-ui/issues/335)) ([38715de](https://github.com/stacklok/codegate-ui/commit/38715de6395b7ae0e2f50fd6ce8f64e4c341c42f)) + ## [0.16.0](https://github.com/stacklok/codegate-ui/compare/v0.15.0...v0.16.0) (2025-02-17) diff --git a/package-lock.json b/package-lock.json index 5c0268d6..fe141cf9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "vite-project", - "version": "0.16.0", + "version": "0.17.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "vite-project", - "version": "0.16.0", + "version": "0.17.0", "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", @@ -36,7 +36,9 @@ "react-markdown": "^9.0.1", "react-router-dom": "^7.1.1", "react-syntax-highlighter": "^15.6.1", + "remark": "^15.0.1", "remark-gfm": "^4.0.0", + "strip-markdown": "^6.0.0", "tailwind-merge": "^2.5.5", "tailwind-variants": "^0.3.1", "tailwindcss-animate": "^1.0.7", @@ -56,7 +58,7 @@ "@types/hast": "^3.0.4", "@types/node": "^22.13.1", "@types/react": "^19.0.2", - "@types/react-dom": "^19.0.2", + "@types/react-dom": "^19.0.3", "@typescript-eslint/parser": "^8.23.0", "@vitejs/plugin-react-swc": "^3.5.0", "@vitest/coverage-istanbul": "^3.0.5", @@ -70,7 +72,7 @@ "eslint-plugin-react-refresh": "^0.4.16", "eslint-plugin-tailwindcss": "3.17.5", "globals": "^15.12.0", - "hast": "^0.0.2", + "hast": "^1.0.0", "husky": "^9.1.6", "jsdom": "^25.0.1", "knip": "^5.43.6", @@ -3774,9 +3776,9 @@ } }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz", - "integrity": "sha512-ssKhA8RNltTZLpG6/QNkCSge+7mBQGUqJRisZ2MDQcEGaK93QESEgWK2iOpIDZ7k9zPVkG5AS3ksvD5ZWxmItw==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", + "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", "cpu": [ "arm" ], @@ -3788,9 +3790,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.29.1.tgz", - "integrity": "sha512-CaRfrV0cd+NIIcVVN/jx+hVLN+VRqnuzLRmfmlzpOzB87ajixsN/+9L5xNmkaUUvEbI5BmIKS+XTwXsHEb65Ew==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", + "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", "cpu": [ "arm64" ], @@ -3802,9 +3804,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.32.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.32.1.tgz", - "integrity": "sha512-zCpKHioQ9KgZToFp5Wvz6zaWbMzYQ2LJHQ+QixDKq52KKrF65ueu6Af4hLlLWHjX1Wf/0G5kSJM9PySW9IrvHA==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", + "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", "cpu": [ "arm64" ], @@ -3815,9 +3817,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.29.1.tgz", - "integrity": "sha512-j/Ej1oanzPjmN0tirRd5K2/nncAhS9W6ICzgxV+9Y5ZsP0hiGhHJXZ2JQ53iSSjj8m6cRY6oB1GMzNn2EUt6Ng==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", + "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", "cpu": [ "x64" ], @@ -3829,9 +3831,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.29.1.tgz", - "integrity": "sha512-91C//G6Dm/cv724tpt7nTyP+JdN12iqeXGFM1SqnljCmi5yTXriH7B1r8AD9dAZByHpKAumqP1Qy2vVNIdLZqw==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", + "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", "cpu": [ "arm64" ], @@ -3843,9 +3845,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.29.1.tgz", - "integrity": "sha512-hEioiEQ9Dec2nIRoeHUP6hr1PSkXzQaCUyqBDQ9I9ik4gCXQZjJMIVzoNLBRGet+hIUb3CISMh9KXuCcWVW/8w==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", + "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", "cpu": [ "x64" ], @@ -3857,9 +3859,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.29.1.tgz", - "integrity": "sha512-Py5vFd5HWYN9zxBv3WMrLAXY3yYJ6Q/aVERoeUFwiDGiMOWsMs7FokXihSOaT/PMWUty/Pj60XDQndK3eAfE6A==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", + "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", "cpu": [ "arm" ], @@ -3871,9 +3873,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.29.1.tgz", - "integrity": "sha512-RiWpGgbayf7LUcuSNIbahr0ys2YnEERD4gYdISA06wa0i8RALrnzflh9Wxii7zQJEB2/Eh74dX4y/sHKLWp5uQ==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", + "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", "cpu": [ "arm" ], @@ -3885,9 +3887,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.29.1.tgz", - "integrity": "sha512-Z80O+taYxTQITWMjm/YqNoe9d10OX6kDh8X5/rFCMuPqsKsSyDilvfg+vd3iXIqtfmp+cnfL1UrYirkaF8SBZA==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", + "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", "cpu": [ "arm64" ], @@ -3899,9 +3901,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.29.1.tgz", - "integrity": "sha512-fOHRtF9gahwJk3QVp01a/GqS4hBEZCV1oKglVVq13kcK3NeVlS4BwIFzOHDbmKzt3i0OuHG4zfRP0YoG5OF/rA==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", + "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", "cpu": [ "arm64" ], @@ -3913,9 +3915,9 @@ ] }, "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.29.1.tgz", - "integrity": "sha512-5a7q3tnlbcg0OodyxcAdrrCxFi0DgXJSoOuidFUzHZ2GixZXQs6Tc3CHmlvqKAmOs5eRde+JJxeIf9DonkmYkw==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", + "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", "cpu": [ "loong64" ], @@ -3927,9 +3929,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.29.1.tgz", - "integrity": "sha512-9b4Mg5Yfz6mRnlSPIdROcfw1BU22FQxmfjlp/CShWwO3LilKQuMISMTtAu/bxmmrE6A902W2cZJuzx8+gJ8e9w==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", + "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", "cpu": [ "ppc64" ], @@ -3941,9 +3943,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.29.1.tgz", - "integrity": "sha512-G5pn0NChlbRM8OJWpJFMX4/i8OEU538uiSv0P6roZcbpe/WfhEO+AT8SHVKfp8qhDQzaz7Q+1/ixMy7hBRidnQ==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", + "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", "cpu": [ "riscv64" ], @@ -3955,9 +3957,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.29.1.tgz", - "integrity": "sha512-WM9lIkNdkhVwiArmLxFXpWndFGuOka4oJOZh8EP3Vb8q5lzdSCBuhjavJsw68Q9AKDGeOOIHYzYm4ZFvmWez5g==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", + "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", "cpu": [ "s390x" ], @@ -3969,9 +3971,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.29.1.tgz", - "integrity": "sha512-87xYCwb0cPGZFoGiErT1eDcssByaLX4fc0z2nRM6eMtV9njAfEE6OW3UniAoDhX4Iq5xQVpE6qO9aJbCFumKYQ==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", + "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", "cpu": [ "x64" ], @@ -3983,9 +3985,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.29.1.tgz", - "integrity": "sha512-xufkSNppNOdVRCEC4WKvlR1FBDyqCSCpQeMMgv9ZyXqqtKBfkw1yfGMTUTs9Qsl6WQbJnsGboWCp7pJGkeMhKA==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", + "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", "cpu": [ "x64" ], @@ -3997,9 +3999,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.29.1.tgz", - "integrity": "sha512-F2OiJ42m77lSkizZQLuC+jiZ2cgueWQL5YC9tjo3AgaEw+KJmVxHGSyQfDUoYR9cci0lAywv2Clmckzulcq6ig==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", + "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", "cpu": [ "arm64" ], @@ -4011,9 +4013,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.29.1.tgz", - "integrity": "sha512-rYRe5S0FcjlOBZQHgbTKNrqxCBUmgDJem/VQTCcTnA2KCabYSWQDrytOzX7avb79cAAweNmMUb/Zw18RNd4mng==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", + "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", "cpu": [ "ia32" ], @@ -4025,9 +4027,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.29.1.tgz", - "integrity": "sha512-+10CMg9vt1MoHj6x1pxyjPSMjHTIlqs8/tBztXvPAx24SKs9jwVnKqHJumlH/IzhaPUaj3T6T6wfZr8okdXaIg==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", + "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", "cpu": [ "x64" ], @@ -4613,9 +4615,9 @@ } }, "node_modules/@types/react-dom": { - "version": "19.0.2", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.2.tgz", - "integrity": "sha512-c1s+7TKFaDRRxr1TxccIX2u7sfCnc3RxkVyBIUA2lCpyqCF+QoAwQ/CBg7bsMdVwP120HEH143VQezKtef5nCg==", + "version": "19.0.3", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.0.3.tgz", + "integrity": "sha512-0Knk+HJiMP/qOZgMyNFamlIjw9OFCsyC2ZbigmEEyXXixgre6IQpm/4V+r3qH4GC1JPvRJKInw+on2rV6YZLeA==", "dev": true, "license": "MIT", "peerDependencies": { @@ -5557,16 +5559,6 @@ "dev": true, "license": "MIT" }, - "node_modules/attach-ware": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/attach-ware/-/attach-ware-1.1.1.tgz", - "integrity": "sha512-OpavlXWZkyE7m28fpCWF/RmxCukC1edukJp9IKjEpZs/O11H3896DkLpK7lMiL8ZDx2yxo9FrZQaeHkyJGcIuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "unherit": "^1.0.0" - } - }, "node_modules/autoprefixer": { "version": "10.4.20", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", @@ -5844,16 +5836,6 @@ "node": ">=6" } }, - "node_modules/camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha512-wzLkDa4K/mzI1OSITC+DUyjgIl/ETNHE9QvYgy6J6Jvqyyz4C0Xfd+lQhb19sX2jMpZV4IssUn0VDVmglV+s4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/camelcase-css": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", @@ -6201,13 +6183,6 @@ "node": ">=6" } }, - "node_modules/co": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/co/-/co-3.1.0.tgz", - "integrity": "sha512-CQsjCRiNObI8AtTsNIBDRMQ4oMR83CzEswHYahClvul7gKk+lDQiOKv+5qh7LQWf5sh6jkZNispz/QlsZxyNgA==", - "dev": true, - "license": "MIT" - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -6632,68 +6607,6 @@ "dev": true, "license": "MIT" }, - "node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "node_modules/dom-serializer/node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/dom-serializer/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "domelementtype": "1" - } - }, - "node_modules/domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, "node_modules/dotenv": { "version": "16.4.7", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", @@ -6779,29 +6692,6 @@ "node": ">=10.13.0" } }, - "node_modules/ent": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.2.tgz", - "integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.3", - "es-errors": "^1.3.0", - "punycode": "^1.4.1", - "safe-regex-test": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ent/node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", - "dev": true, - "license": "MIT" - }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", @@ -7029,13 +6919,6 @@ "node": ">=6" } }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true, - "license": "MIT" - }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -8195,22 +8078,12 @@ } }, "node_modules/hast": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/hast/-/hast-0.0.2.tgz", - "integrity": "sha512-1MrzC9MtAYhzLix2w++pGEtRyCm6N1fcxCjx+1xJo/92fNDRFemFaum18XWd8No3f+FgT9lv6fKOC8LZRcxxuw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hast/-/hast-1.0.0.tgz", + "integrity": "sha512-vFUqlRV5C+xqP76Wwq2SrM0kipnmpxJm7OfvVXpB35Fp+Fn4MV+ozr+JZr5qFvyR1q/U+Foim2x+3P+x9S1PLA==", + "deprecated": "Renamed to rehype", "dev": true, - "license": "MIT", - "dependencies": { - "bail": "^1.0.0", - "camelcase": "^1.2.1", - "ent": "^2.2.0", - "escape-html": "^1.0.3", - "htmlparser2": "^3.8.3", - "param-case": "^1.1.1", - "property-information": "^2.0.0", - "trim": "0.0.1", - "unified": "^2.1.0" - } + "license": "MIT" }, "node_modules/hast-util-parse-selector": { "version": "2.2.5", @@ -8262,46 +8135,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/hast/node_modules/bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/hast/node_modules/property-information": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-2.0.0.tgz", - "integrity": "sha512-8oVcjnCeqANq/exCzgse3D47GBmgOuI47vNya7xBIJhUXeh49AjZuXWw2gTh1UuN4rfwz5pEv2ZFzu45vBby5A==", - "dev": true, - "license": "MIT" - }, - "node_modules/hast/node_modules/unified": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/unified/-/unified-2.1.4.tgz", - "integrity": "sha512-qa4nA26ms49OczPueTt7G46r89TOlwAJ4pEk2U4mwkV1wNhjttItF03SE/YnfkgWg14tzmAHXGhJp2GhDYwn1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "attach-ware": "^1.0.0", - "bail": "^1.0.0", - "extend": "^3.0.0", - "unherit": "^1.0.4", - "vfile": "^1.0.0", - "ware": "^1.3.0" - } - }, - "node_modules/hast/node_modules/vfile": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-1.4.0.tgz", - "integrity": "sha512-7Fz639rwERslMqQCuf1/0H4Tqe2q484Xl6X/jsKqrP7IjFcDODFURhv0GekMnImpbj9pTOojtqL7r39LJJkjGA==", - "dev": true, - "license": "MIT" - }, "node_modules/hastscript": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", @@ -8419,28 +8252,6 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "node_modules/htmlparser2/node_modules/entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true, - "license": "BSD-2-Clause" - }, "node_modules/http-proxy-agent": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", @@ -8555,13 +8366,6 @@ "node": ">=8" } }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, "node_modules/inline-style-parser": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.4.tgz", @@ -9700,13 +9504,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==", - "dev": true, - "license": "MIT" - }, "node_modules/lowlight": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz", @@ -11319,16 +11116,6 @@ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, - "node_modules/param-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-1.1.2.tgz", - "integrity": "sha512-gksk6zeZQxwBm1AHsKh+XDFsTGf1LvdZSkkpSIkfDtzW+EQj/P2PBgNb3Cs0Y9Xxqmbciv2JZe3fWU6Xbher+Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "sentence-case": "^1.1.2" - } - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -11543,9 +11330,9 @@ } }, "node_modules/postcss": { - "version": "8.4.49", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz", - "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz", + "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==", "funding": [ { "type": "opencollective", @@ -11562,7 +11349,7 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", + "nanoid": "^3.3.8", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, @@ -12305,21 +12092,6 @@ "pify": "^2.3.0" } }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -12512,6 +12284,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/remark": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/remark/-/remark-15.0.1.tgz", + "integrity": "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==", + "dependencies": { + "@types/mdast": "^4.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-gfm": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.0.tgz", @@ -12694,9 +12481,9 @@ "license": "MIT" }, "node_modules/rollup": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.29.1.tgz", - "integrity": "sha512-RaJ45M/kmJUzSWDs1Nnd5DdV4eerC98idtUOVr6FfKcgxqvjwHmxc5upLF9qZU9EpsVzzhleFahrT3shLuJzIw==", + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", + "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", "dev": true, "license": "MIT", "dependencies": { @@ -12710,42 +12497,28 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.29.1", - "@rollup/rollup-android-arm64": "4.29.1", - "@rollup/rollup-darwin-arm64": "4.29.1", - "@rollup/rollup-darwin-x64": "4.29.1", - "@rollup/rollup-freebsd-arm64": "4.29.1", - "@rollup/rollup-freebsd-x64": "4.29.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.29.1", - "@rollup/rollup-linux-arm-musleabihf": "4.29.1", - "@rollup/rollup-linux-arm64-gnu": "4.29.1", - "@rollup/rollup-linux-arm64-musl": "4.29.1", - "@rollup/rollup-linux-loongarch64-gnu": "4.29.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.29.1", - "@rollup/rollup-linux-riscv64-gnu": "4.29.1", - "@rollup/rollup-linux-s390x-gnu": "4.29.1", - "@rollup/rollup-linux-x64-gnu": "4.29.1", - "@rollup/rollup-linux-x64-musl": "4.29.1", - "@rollup/rollup-win32-arm64-msvc": "4.29.1", - "@rollup/rollup-win32-ia32-msvc": "4.29.1", - "@rollup/rollup-win32-x64-msvc": "4.29.1", + "@rollup/rollup-android-arm-eabi": "4.34.8", + "@rollup/rollup-android-arm64": "4.34.8", + "@rollup/rollup-darwin-arm64": "4.34.8", + "@rollup/rollup-darwin-x64": "4.34.8", + "@rollup/rollup-freebsd-arm64": "4.34.8", + "@rollup/rollup-freebsd-x64": "4.34.8", + "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", + "@rollup/rollup-linux-arm-musleabihf": "4.34.8", + "@rollup/rollup-linux-arm64-gnu": "4.34.8", + "@rollup/rollup-linux-arm64-musl": "4.34.8", + "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", + "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", + "@rollup/rollup-linux-riscv64-gnu": "4.34.8", + "@rollup/rollup-linux-s390x-gnu": "4.34.8", + "@rollup/rollup-linux-x64-gnu": "4.34.8", + "@rollup/rollup-linux-x64-musl": "4.34.8", + "@rollup/rollup-win32-arm64-msvc": "4.34.8", + "@rollup/rollup-win32-ia32-msvc": "4.34.8", + "@rollup/rollup-win32-x64-msvc": "4.34.8", "fsevents": "~2.3.2" } }, - "node_modules/rollup/node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.29.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.29.1.tgz", - "integrity": "sha512-2ORr7T31Y0Mnk6qNuwtyNmy14MunTAMx06VAPI6/Ju52W10zk1i7i5U3vlDRWjhOI5quBcrvhkCHyF76bI7kEw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, "node_modules/rrweb-cssom": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", @@ -12796,27 +12569,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/safe-push-apply": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", @@ -12888,16 +12640,6 @@ "semver": "bin/semver.js" } }, - "node_modules/sentence-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-1.1.3.tgz", - "integrity": "sha512-laa/UDTPXsrQnoN/Kc8ZO7gTeEjMsuPiDgUCk9N0iINRZvqAMCTXjGl8+tD27op1eF/JHbdUlEUmovDh6AX7sA==", - "dev": true, - "license": "MIT", - "dependencies": { - "lower-case": "^1.1.1" - } - }, "node_modules/set-cookie-parser": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", @@ -13216,16 +12958,6 @@ "dev": true, "license": "MIT" }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-argv": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", @@ -13464,6 +13196,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-markdown": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-markdown/-/strip-markdown-6.0.0.tgz", + "integrity": "sha512-mSa8FtUoX3ExJYDkjPUTC14xaBAn4Ik5GPQD45G5E2egAmeV3kHgVSTfIoSDggbF6Pk9stahVgqsLCNExv6jHw==", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/style-to-object": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.8.tgz", @@ -13911,13 +13655,6 @@ "node": ">=18" } }, - "node_modules/trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==", - "deprecated": "Use String.prototype.trim() instead", - "dev": true - }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", @@ -14241,21 +13978,6 @@ "dev": true, "license": "MIT" }, - "node_modules/unherit": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", - "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.0", - "xtend": "^4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/unified": { "version": "11.0.5", "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", @@ -14505,15 +14227,15 @@ } }, "node_modules/vite": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.0.7.tgz", - "integrity": "sha512-RDt8r/7qx9940f8FcOIAH9PTViRrghKaK2K1jY3RaAURrEUbm9Du1mJ72G+jlhtG3WwodnfzY8ORQZbBavZEAQ==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.1.0.tgz", + "integrity": "sha512-RjjMipCKVoR4hVfPY6GQTgveinjNuyLw+qruksLDvA5ktI1150VmcMBKmQaEWJhg/j6Uaf6dNCNA0AfdzUb/hQ==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.24.2", - "postcss": "^8.4.49", - "rollup": "^4.23.0" + "postcss": "^8.5.1", + "rollup": "^4.30.1" }, "bin": { "vite": "bin/vite.js" @@ -14848,16 +14570,6 @@ "node": ">=18" } }, - "node_modules/ware": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ware/-/ware-1.3.0.tgz", - "integrity": "sha512-Y2HUDMktriUm+SR2gZWxlrszcgtXExlhQYZ8QJNYbl22jum00KIUcHJ/h/sdAXhWTJcbSkiMYN9Z2tWbWYSrrw==", - "dev": true, - "license": "MIT", - "dependencies": { - "wrap-fn": "^0.1.0" - } - }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -15152,16 +14864,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/wrap-fn": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/wrap-fn/-/wrap-fn-0.1.5.tgz", - "integrity": "sha512-xDLdGx0M8JQw9QDAC9s5NUxtg9MI09F6Vbxa2LYoSoCvzJnx2n81YMIfykmXEGsUvuLaxnblJTzhSOjUOX37ag==", - "dev": true, - "license": "MIT", - "dependencies": { - "co": "3.1.0" - } - }, "node_modules/ws": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", diff --git a/package.json b/package.json index 9d8cac23..4478ea30 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "vite-project", "private": true, - "version": "0.16.0", + "version": "0.17.0", "type": "module", "scripts": { "dev": "vite", @@ -49,7 +49,9 @@ "react-markdown": "^9.0.1", "react-router-dom": "^7.1.1", "react-syntax-highlighter": "^15.6.1", + "remark": "^15.0.1", "remark-gfm": "^4.0.0", + "strip-markdown": "^6.0.0", "tailwind-merge": "^2.5.5", "tailwind-variants": "^0.3.1", "tailwindcss-animate": "^1.0.7", @@ -69,7 +71,7 @@ "@types/hast": "^3.0.4", "@types/node": "^22.13.1", "@types/react": "^19.0.2", - "@types/react-dom": "^19.0.2", + "@types/react-dom": "^19.0.3", "@typescript-eslint/parser": "^8.23.0", "@vitejs/plugin-react-swc": "^3.5.0", "@vitest/coverage-istanbul": "^3.0.5", @@ -83,7 +85,7 @@ "eslint-plugin-react-refresh": "^0.4.16", "eslint-plugin-tailwindcss": "3.17.5", "globals": "^15.12.0", - "hast": "^0.0.2", + "hast": "^1.0.0", "husky": "^9.1.6", "jsdom": "^25.0.1", "knip": "^5.43.6", diff --git a/src/api/generated/@tanstack/react-query.gen.ts b/src/api/generated/@tanstack/react-query.gen.ts index 102ed855..a22a7421 100644 --- a/src/api/generated/@tanstack/react-query.gen.ts +++ b/src/api/generated/@tanstack/react-query.gen.ts @@ -28,6 +28,7 @@ import { v1DeleteWorkspaceCustomInstructions, v1GetWorkspaceMuxes, v1SetWorkspaceMuxes, + v1ListWorkspacesByProvider, v1StreamSse, v1VersionCheck, v1GetWorkspaceTokenUsage, @@ -76,6 +77,7 @@ import type { V1SetWorkspaceMuxesData, V1SetWorkspaceMuxesError, V1SetWorkspaceMuxesResponse, + V1ListWorkspacesByProviderData, V1GetWorkspaceTokenUsageData, } from '../types.gen' @@ -687,6 +689,27 @@ export const v1SetWorkspaceMuxesMutation = ( return mutationOptions } +export const v1ListWorkspacesByProviderQueryKey = ( + options: OptionsLegacyParser +) => [createQueryKey('v1ListWorkspacesByProvider', options)] + +export const v1ListWorkspacesByProviderOptions = ( + options: OptionsLegacyParser +) => { + return queryOptions({ + queryFn: async ({ queryKey, signal }) => { + const { data } = await v1ListWorkspacesByProvider({ + ...options, + ...queryKey[0], + signal, + throwOnError: true, + }) + return data + }, + queryKey: v1ListWorkspacesByProviderQueryKey(options), + }) +} + export const v1StreamSseQueryKey = (options?: OptionsLegacyParser) => [ createQueryKey('v1StreamSse', options), ] diff --git a/src/api/generated/sdk.gen.ts b/src/api/generated/sdk.gen.ts index 9834d09b..e9d216d9 100644 --- a/src/api/generated/sdk.gen.ts +++ b/src/api/generated/sdk.gen.ts @@ -73,6 +73,9 @@ import type { V1SetWorkspaceMuxesData, V1SetWorkspaceMuxesError, V1SetWorkspaceMuxesResponse, + V1ListWorkspacesByProviderData, + V1ListWorkspacesByProviderError, + V1ListWorkspacesByProviderResponse, V1StreamSseError, V1StreamSseResponse, V1VersionCheckError, @@ -512,6 +515,25 @@ export const v1SetWorkspaceMuxes = ( }) } +/** + * List Workspaces By Provider + * List workspaces by provider ID. + */ +export const v1ListWorkspacesByProvider = < + ThrowOnError extends boolean = false, +>( + options: OptionsLegacyParser +) => { + return (options?.client ?? client).get< + V1ListWorkspacesByProviderResponse, + V1ListWorkspacesByProviderError, + ThrowOnError + >({ + ...options, + url: '/api/v1/workspaces/{provider_id}', + }) +} + /** * Stream Sse * Send alerts event diff --git a/src/api/generated/types.gen.ts b/src/api/generated/types.gen.ts index 5f2dc9be..50634d20 100644 --- a/src/api/generated/types.gen.ts +++ b/src/api/generated/types.gen.ts @@ -35,11 +35,11 @@ export type Alert = { | { [key: string]: unknown } - | null; - trigger_type: string; - trigger_category: AlertSeverity; - timestamp: string; -}; + | null + trigger_type: string + trigger_category: AlertSeverity + timestamp: string +} /** * Represents an alert with it's respective conversation. @@ -60,8 +60,8 @@ export type AlertConversation = { } export enum AlertSeverity { - INFO = "info", - CRITICAL = "critical", + INFO = 'info', + CRITICAL = 'critical', } /** @@ -111,6 +111,7 @@ export type Conversation = { export type CreateOrRenameWorkspaceRequest = { name: string + config?: WorkspaceConfig | null rename_to?: string | null } @@ -145,15 +146,16 @@ export type ModelByProvider = { * Represents the different types of matchers we support. */ export enum MuxMatcherType { - CATCH_ALL = "catch_all", - FILENAME_MATCH = "filename_match", - REQUEST_TYPE_MATCH = "request_type_match", + CATCH_ALL = 'catch_all', + FILENAME_MATCH = 'filename_match', + REQUEST_TYPE_MATCH = 'request_type_match', } /** * Represents a mux rule for a provider. */ export type MuxRule = { + provider_name?: string | null provider_id: string model: string matcher_type: MuxMatcherType @@ -251,6 +253,20 @@ export type Workspace = { is_active: boolean } +export type WorkspaceConfig = { + system_prompt: string + muxing_rules: Array +} + +/** + * Returns a workspace ID with model name + */ +export type WorkspaceWithModel = { + id: string + name: string + provider_model_name: string +} + export type HealthCheckHealthGetResponse = unknown export type HealthCheckHealthGetError = unknown @@ -462,6 +478,16 @@ export type V1SetWorkspaceMuxesResponse = void export type V1SetWorkspaceMuxesError = HTTPValidationError +export type V1ListWorkspacesByProviderData = { + path: { + provider_id: string + } +} + +export type V1ListWorkspacesByProviderResponse = Array + +export type V1ListWorkspacesByProviderError = HTTPValidationError + export type V1StreamSseResponse = unknown export type V1StreamSseError = unknown diff --git a/src/api/openapi.json b/src/api/openapi.json index cde65b55..a6d16753 100644 --- a/src/api/openapi.json +++ b/src/api/openapi.json @@ -989,6 +989,55 @@ } } }, + "/api/v1/workspaces/{provider_id}": { + "get": { + "tags": [ + "CodeGate API", + "Workspaces" + ], + "summary": "List Workspaces By Provider", + "description": "List workspaces by provider ID.", + "operationId": "v1_list_workspaces_by_provider", + "parameters": [ + { + "name": "provider_id", + "in": "path", + "required": true, + "schema": { + "type": "string", + "format": "uuid", + "title": "Provider Id" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WorkspaceWithModel" + }, + "title": "Response V1 List Workspaces By Provider" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, "/api/v1/alerts_notification": { "get": { "tags": [ @@ -1478,6 +1527,16 @@ "type": "string", "title": "Name" }, + "config": { + "anyOf": [ + { + "$ref": "#/components/schemas/WorkspaceConfig" + }, + { + "type": "null" + } + ] + }, "rename_to": { "anyOf": [ { @@ -1590,6 +1649,17 @@ }, "MuxRule": { "properties": { + "provider_name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider Name" + }, "provider_id": { "type": "string", "title": "Provider Id" @@ -1842,6 +1912,52 @@ "is_active" ], "title": "Workspace" + }, + "WorkspaceConfig": { + "properties": { + "system_prompt": { + "type": "string", + "title": "System Prompt" + }, + "muxing_rules": { + "items": { + "$ref": "#/components/schemas/MuxRule" + }, + "type": "array", + "title": "Muxing Rules" + } + }, + "type": "object", + "required": [ + "system_prompt", + "muxing_rules" + ], + "title": "WorkspaceConfig" + }, + "WorkspaceWithModel": { + "properties": { + "id": { + "type": "string", + "title": "Id" + }, + "name": { + "type": "string", + "pattern": "^[a-zA-Z0-9_-]+$", + "title": "Name" + }, + "provider_model_name": { + "type": "string", + "title": "Provider Model Name" + } + }, + "type": "object", + "required": [ + "id", + "name", + "provider_model_name" + ], + "title": "WorkspaceWithModel", + "description": "Returns a workspace ID with model name" } } } diff --git a/src/components/Markdown.tsx b/src/components/Markdown.tsx index e183a01e..279e960a 100644 --- a/src/components/Markdown.tsx +++ b/src/components/Markdown.tsx @@ -86,6 +86,9 @@ const CodeInline = ({ language={language} codeTagProps={{ className: 'px-1 py-0.5 bg-gray-200 rounded-sm border border-gray-400', + style: { + whiteSpace: 'unset', + }, }} useInlineStyles={false} PreTag="span" diff --git a/src/constants/empty-state-strings.ts b/src/constants/empty-state-strings.ts index 58b54a56..1b1572d4 100644 --- a/src/constants/empty-state-strings.ts +++ b/src/constants/empty-state-strings.ts @@ -7,6 +7,8 @@ export const emptyStateStrings = { anErrorOccurred: 'An error occurred', noLeakedSecretsDetected: 'No leaked secrets detected', noMaliciousPackagesDetected: 'No malicious packages detected', + noPIIDetected: + 'No leaked personally identifiable information (PII) detected', noSearchResultsFor: (x: string | undefined): string => !x ? 'No search results' : `No search results for "${x}"`, }, @@ -22,6 +24,8 @@ export const emptyStateStrings = { 'Messages are issues that CodeGate has detected and mitigated in your interactions with the LLM.', secretsDesc: 'CodeGate helps you protect sensitive information from being accidentally exposed to AI models and third-party AI provider systems by redacting detected secrets from your prompts using encryption.', + piiDesc: + 'CodeGate helps you protect sensitive personally identifiable information (PII) from being accidentally exposed to AI models and third-party AI provider systems by redacting detected PII from your prompts using encryption.', maliciousDesc: "CodeGate's dependency risk insight helps protect your codebase from malicious or vulnerable dependencies. It identifies potentially risky packages and suggests fixed versions or alternative packages to consider.", }, diff --git a/src/features/dashboard-messages/components/__tests__/table-messages.alerts.test.tsx b/src/features/dashboard-messages/components/__tests__/table-messages.alerts.test.tsx index 1d12083a..ab7d0462 100644 --- a/src/features/dashboard-messages/components/__tests__/table-messages.alerts.test.tsx +++ b/src/features/dashboard-messages/components/__tests__/table-messages.alerts.test.tsx @@ -33,6 +33,11 @@ it('shows zero in alerts counts when no alerts', async () => { name: /secrets count/i, }) ).toHaveTextContent('0') + expect( + screen.getByRole('button', { + name: /personally identifiable information.*count/i, + }) + ).toHaveTextContent('0') }) it('shows count of malicious alerts in row', async () => { @@ -80,3 +85,26 @@ it('shows count of secret alerts in row', async () => { }) ).toHaveTextContent('10') }) + +it('shows count of pii alerts in row', async () => { + server.use( + http.get(mswEndpoint('/api/v1/workspaces/:workspace_name/messages'), () => + HttpResponse.json([ + mockConversation({ + alertsConfig: { numAlerts: 10, type: 'pii' }, + }), + ]) + ) + ) + render() + + await waitFor(() => { + expect(screen.queryByText(/loading.../i)).not.toBeInTheDocument() + }) + + expect( + screen.getByRole('button', { + name: /pii/i, + }) + ).toHaveTextContent('10') +}) diff --git a/src/features/dashboard-messages/components/__tests__/table-messages.empty-state.test.tsx b/src/features/dashboard-messages/components/__tests__/table-messages.empty-state.test.tsx index 1d38805c..556232f5 100644 --- a/src/features/dashboard-messages/components/__tests__/table-messages.empty-state.test.tsx +++ b/src/features/dashboard-messages/components/__tests__/table-messages.empty-state.test.tsx @@ -304,6 +304,48 @@ const TEST_CASES: TestCase[] = [ actions: null, }, }, + { + testDescription: 'Has alerts, view is "pii"', + handlers: [ + http.get(mswEndpoint('/api/v1/workspaces'), () => { + return HttpResponse.json({ + workspaces: [ + { + name: 'default', + is_active: true, + }, + { + name: 'foo-bar', + is_active: false, + }, + ], + }) + }), + http.get(mswEndpoint('/api/v1/workspaces/archive'), () => { + return HttpResponse.json({ + workspaces: [], + }) + }), + http.get( + mswEndpoint('/api/v1/workspaces/:workspace_name/messages'), + () => { + return HttpResponse.json( + Array.from({ length: 10 }).map(() => mockAlert({ type: 'pii' })) + ) + } + ), + ], + searchParams: { + view: AlertsFilterView.PII, + search: null, + }, + expected: { + title: emptyStateStrings.title.noPIIDetected, + body: emptyStateStrings.body.piiDesc, + illustrationTestId: IllustrationTestId.DONE, + actions: null, + }, + }, ] test.each(TEST_CASES)('$testDescription', async (testCase) => { diff --git a/src/features/dashboard-messages/components/__tests__/tabs-messages.test.tsx b/src/features/dashboard-messages/components/__tests__/tabs-messages.test.tsx index 4c83f9ad..f4a0bd53 100644 --- a/src/features/dashboard-messages/components/__tests__/tabs-messages.test.tsx +++ b/src/features/dashboard-messages/components/__tests__/tabs-messages.test.tsx @@ -40,56 +40,42 @@ test('shows correct count of all packages', async () => { }) }) -test('shows correct count of malicious packages', async () => { - server.use( - http.get(mswEndpoint('/api/v1/workspaces/:workspace_name/messages'), () => { - return HttpResponse.json( - Array.from({ length: 13 }).map(() => - mockConversation({ - alertsConfig: { - type: 'malicious', - numAlerts: 1, - }, - }) - ) +const filteredCases = [ + { tabLabel: /malicious/i, alertType: 'malicious' as const, count: 13 }, + { tabLabel: /secrets/i, alertType: 'secret' as const, count: 10 }, + { tabLabel: /pii/i, alertType: 'pii' as const, count: 9 }, +] + +filteredCases.forEach(({ tabLabel, alertType, count }) => { + test(`shows correct count of ${alertType} packages`, async () => { + server.use( + http.get( + mswEndpoint('/api/v1/workspaces/:workspace_name/messages'), + () => { + return HttpResponse.json( + Array.from({ length: count }).map(() => + mockConversation({ + alertsConfig: { + type: alertType, + numAlerts: 1, + }, + }) + ) + ) + } ) - }) - ) + ) - const { getByRole } = render( - -
foo
-
- ) + const { getByRole } = render( + +
foo
+
+ ) - await waitFor(() => { - expect(getByRole('tab', { name: /malicious/i })).toHaveTextContent('13') - }) -}) - -test('shows correct count of secret packages', async () => { - server.use( - http.get(mswEndpoint('/api/v1/workspaces/:workspace_name/messages'), () => { - return HttpResponse.json( - Array.from({ length: 13 }).map(() => - mockConversation({ - alertsConfig: { - type: 'secret', - numAlerts: 1, - }, - }) - ) + await waitFor(() => { + expect(getByRole('tab', { name: tabLabel })).toHaveTextContent( + String(count) ) }) - ) - - const { getByRole } = render( - -
foo
-
- ) - - await waitFor(() => { - expect(getByRole('tab', { name: /secrets/i })).toHaveTextContent('13') }) }) diff --git a/src/features/dashboard-messages/components/conversation-summary.tsx b/src/features/dashboard-messages/components/conversation-summary.tsx index 549a9e03..bb60f0ea 100644 --- a/src/features/dashboard-messages/components/conversation-summary.tsx +++ b/src/features/dashboard-messages/components/conversation-summary.tsx @@ -12,6 +12,7 @@ import { Hash01, Key01, PackageX, + Passport, Server05, } from '@untitled-ui/icons-react' @@ -51,8 +52,8 @@ function AlertsSummaryCount({ }: { count: number type: { - singular: 'malicious package' | 'secret' - plural: 'malicious packages' | 'secrets' + singular: string + plural: string } }) { const typeText = count === 1 ? type.singular : type.plural @@ -97,9 +98,9 @@ export function ConversationSummary({ }: { conversation: Conversation }) { - const { malicious, secrets } = conversation.alerts + const { malicious, secrets, pii } = conversation.alerts ? countConversationAlerts(conversation.alerts) - : { malicious: 0, secrets: 0 } + : { malicious: 0, secrets: 0, pii: 0 } return (
@@ -166,6 +167,19 @@ export function ConversationSummary({ /> } /> + + } + />
) diff --git a/src/features/dashboard-messages/components/table-messages-empty-state.tsx b/src/features/dashboard-messages/components/table-messages-empty-state.tsx index cc378f72..8a109a80 100644 --- a/src/features/dashboard-messages/components/table-messages-empty-state.tsx +++ b/src/features/dashboard-messages/components/table-messages-empty-state.tsx @@ -120,6 +120,17 @@ function EmptyStateSecrets() { ) } +function EmptyStatePII() { + return ( + + ) +} + export function EmptyStateError() { return ( ) + .with( + { + hasWorkspaceMessages: true, + hasMultipleWorkspaces: P.any, + view: AlertsFilterView.PII, + isLoading: false, + }, + () => + ) .with( { hasWorkspaceMessages: true, diff --git a/src/features/dashboard-messages/components/table-messages.tsx b/src/features/dashboard-messages/components/table-messages.tsx index d082251a..3dd2ac25 100644 --- a/src/features/dashboard-messages/components/table-messages.tsx +++ b/src/features/dashboard-messages/components/table-messages.tsx @@ -11,12 +11,14 @@ import { TooltipTrigger, } from '@stacklok/ui-kit' import { Alert, Conversation, QuestionType } from '@/api/generated' +import { remark } from 'remark' +import strip from 'strip-markdown' import { useClientSidePagination } from '@/hooks/useClientSidePagination' import { TableAlertTokenUsage } from './table-alert-token-usage' import { useMessagesFilterSearchParams } from '../hooks/use-messages-filter-search-params' -import { Key01, PackageX } from '@untitled-ui/icons-react' +import { Key01, PackageX, Passport } from '@untitled-ui/icons-react' import { EmptyStateError, TableMessagesEmptyState, @@ -31,11 +33,14 @@ import { TableMessagesColumn, } from '../constants/table-messages-columns' import { formatTime } from '@/lib/format-time' +import { isAlertPii } from '@/lib/is-alert-pii' const getPromptText = (conversation: Conversation) => { - return (conversation.question_answers[0]?.question?.message ?? 'N/A') - .trim() - .slice(0, 200) // arbitrary slice to prevent long prompts + const markdownSource = + conversation.question_answers[0]?.question?.message ?? 'N/A' + const fullText = remark().use(strip).processSync(markdownSource) + + return fullText.toString().trim().slice(0, 200) // arbitrary slice to prevent long prompts } function getTypeText(type: QuestionType) { @@ -52,10 +57,12 @@ function getTypeText(type: QuestionType) { function countAlerts(alerts: Alert[]): { secrets: number malicious: number + pii: number } { return { secrets: alerts.filter(isAlertSecret).length, malicious: alerts.filter(isAlertMalicious).length, + pii: alerts.filter(isAlertPii).length, } } @@ -93,7 +100,7 @@ function AlertsSummaryCount({ } function AlertsSummaryCellContent({ alerts }: { alerts: Alert[] }) { - const { malicious, secrets } = countAlerts(alerts) + const { malicious, secrets, pii } = countAlerts(alerts) return (
@@ -113,6 +120,14 @@ function AlertsSummaryCellContent({ alerts }: { alerts: Alert[] }) { count={secrets} icon={Key01} /> +
) } diff --git a/src/features/dashboard-messages/components/tabs-messages.tsx b/src/features/dashboard-messages/components/tabs-messages.tsx index 8b163b18..52ac99a3 100644 --- a/src/features/dashboard-messages/components/tabs-messages.tsx +++ b/src/features/dashboard-messages/components/tabs-messages.tsx @@ -18,11 +18,13 @@ import { import { SearchFieldMessages } from './search-field-messages' import { tv } from 'tailwind-variants' import { useQueryGetWorkspaceMessages } from '@/hooks/use-query-get-workspace-messages' +import { isConversationWithPII } from '@/lib/is-alert-pii' type AlertsCount = { all: number malicious: number secrets: number + pii: number } function select(data: V1GetWorkspaceMessagesResponse): AlertsCount { @@ -36,10 +38,13 @@ function select(data: V1GetWorkspaceMessagesResponse): AlertsCount { isConversationWithSecretAlerts, ]).length + const pii: number = multiFilter(data, [isConversationWithPII]).length + return { all, malicious, secrets, + pii, } } @@ -103,6 +108,7 @@ export function TabsMessages({ children }: { children: React.ReactNode }) { count={data?.secrets ?? 0} id={AlertsFilterView.SECRETS} /> + diff --git a/src/features/dashboard-messages/hooks/use-messages-filter-search-params.ts b/src/features/dashboard-messages/hooks/use-messages-filter-search-params.ts index 4144a9ff..a311d16e 100644 --- a/src/features/dashboard-messages/hooks/use-messages-filter-search-params.ts +++ b/src/features/dashboard-messages/hooks/use-messages-filter-search-params.ts @@ -6,6 +6,7 @@ export enum AlertsFilterView { ALL = 'all', MALICIOUS = 'malicious', SECRETS = 'secrets', + PII = 'pii', } const alertsFilterSchema = z.object({ diff --git a/src/features/dashboard-messages/hooks/use-query-get-workspace-messages-table.ts b/src/features/dashboard-messages/hooks/use-query-get-workspace-messages-table.ts index fc9a3c5f..f82b9b6f 100644 --- a/src/features/dashboard-messages/hooks/use-query-get-workspace-messages-table.ts +++ b/src/features/dashboard-messages/hooks/use-query-get-workspace-messages-table.ts @@ -9,6 +9,7 @@ import { isConversationWithMaliciousAlerts } from '../../../lib/is-alert-malicio import { isConversationWithSecretAlerts } from '../../../lib/is-alert-secret' import { filterMessagesBySubstring } from '../lib/filter-messages-by-substring' import { useQueryGetWorkspaceMessages } from '@/hooks/use-query-get-workspace-messages' +import { isConversationWithPII } from '@/lib/is-alert-pii' const FILTER: Record< AlertsFilterView, @@ -17,6 +18,7 @@ const FILTER: Record< all: () => true, malicious: isConversationWithMaliciousAlerts, secrets: isConversationWithSecretAlerts, + pii: isConversationWithPII, } export function useQueryGetWorkspaceMessagesTable() { diff --git a/src/features/dashboard-messages/lib/count-conversation-alerts.ts b/src/features/dashboard-messages/lib/count-conversation-alerts.ts index 9e88253d..13931bed 100644 --- a/src/features/dashboard-messages/lib/count-conversation-alerts.ts +++ b/src/features/dashboard-messages/lib/count-conversation-alerts.ts @@ -1,13 +1,16 @@ import { Alert } from '@/api/generated' import { isAlertMalicious } from '@/lib/is-alert-malicious' +import { isAlertPii } from '@/lib/is-alert-pii' import { isAlertSecret } from '@/lib/is-alert-secret' export function countConversationAlerts(alerts: Alert[]): { secrets: number malicious: number + pii: number } { return { secrets: alerts.filter(isAlertSecret).length, malicious: alerts.filter(isAlertMalicious).length, + pii: alerts.filter(isAlertPii).length, } } diff --git a/src/features/providers/components/table-providers.tsx b/src/features/providers/components/table-providers.tsx index a24bea52..d10dfab4 100644 --- a/src/features/providers/components/table-providers.tsx +++ b/src/features/providers/components/table-providers.tsx @@ -51,12 +51,12 @@ const COLUMNS: Column[] = [ function CellRenderer({ column, row, - deleteProvider, }: { column: Column row: ProviderEndpoint - deleteProvider: () => void }) { + const deleteProvider = useConfirmDeleteProvider(row.id) + return match(column.id) .with(COLUMN_MAP.provider, () => ( <> @@ -90,7 +90,15 @@ function CellRenderer({ )) .with(COLUMN_MAP.configuration, () => ( - )) @@ -99,7 +107,6 @@ function CellRenderer({ export function TableProviders() { const { data: providers = [] } = useProviders() - const deleteProvider = useConfirmDeleteProvider() return ( @@ -117,15 +124,7 @@ export function TableProviders() { id={column.id} alignment={column.alignment} > - { - deleteProvider({ - path: { provider_id: row.id as string }, - }) - }} - /> + )} diff --git a/src/features/providers/components/workspaces-by-provider.tsx b/src/features/providers/components/workspaces-by-provider.tsx new file mode 100644 index 00000000..63a35df0 --- /dev/null +++ b/src/features/providers/components/workspaces-by-provider.tsx @@ -0,0 +1,25 @@ +import { V1ListWorkspacesByProviderResponse } from '@/api/generated' +import { Badge } from '@stacklok/ui-kit' +import { uniqBy } from 'lodash' + +export function WorkspacesByProvider({ + workspaces = [], +}: { + workspaces: V1ListWorkspacesByProviderResponse | undefined +}) { + if (workspaces.length === 0) return null + return ( +
+

The following workspaces will be impacted by this action

+
+ {uniqBy(workspaces, 'name').map((item, index) => { + return ( + + {item.name} + + ) + })} +
+
+ ) +} diff --git a/src/features/providers/hooks/use-confirm-delete-provider.tsx b/src/features/providers/hooks/use-confirm-delete-provider.tsx index 3cce4bd6..24b23623 100644 --- a/src/features/providers/hooks/use-confirm-delete-provider.tsx +++ b/src/features/providers/hooks/use-confirm-delete-provider.tsx @@ -1,19 +1,22 @@ import { useConfirm } from '@/hooks/use-confirm' import { useCallback } from 'react' import { useMutationDeleteProvider } from './use-mutation-delete-provider' +import { useQueryWorkspacesByProvider } from './use-query-workspaces-by-provider' +import { WorkspacesByProvider } from '../components/workspaces-by-provider' -export function useConfirmDeleteProvider() { +export function useConfirmDeleteProvider( + providerId: string | undefined | null +) { const { mutateAsync: deleteProvider } = useMutationDeleteProvider() - + const { data: workspaces } = useQueryWorkspacesByProvider(providerId) const { confirm } = useConfirm() return useCallback( async (...params: Parameters) => { const answer = await confirm( <> -

- Are you sure you want to permanently delete this provider? -

+ +

Are you sure you want to permanently delete this provider?

, { buttons: { @@ -28,6 +31,6 @@ export function useConfirmDeleteProvider() { return deleteProvider(...params) } }, - [confirm, deleteProvider] + [confirm, deleteProvider, workspaces] ) } diff --git a/src/features/providers/hooks/use-invalidate-providers-queries.ts b/src/features/providers/hooks/use-invalidate-providers-queries.ts index 3c147681..d18dc080 100644 --- a/src/features/providers/hooks/use-invalidate-providers-queries.ts +++ b/src/features/providers/hooks/use-invalidate-providers-queries.ts @@ -1,6 +1,7 @@ import { v1ListAllModelsForAllProvidersQueryKey, v1ListProviderEndpointsQueryKey, + v1ListWorkspacesByProviderQueryKey, } from '@/api/generated/@tanstack/react-query.gen' import { useQueryClient } from '@tanstack/react-query' import { useCallback } from 'react' @@ -13,6 +14,7 @@ export function useInvalidateProvidersQueries() { invalidateQueries(queryClient, [ v1ListProviderEndpointsQueryKey, v1ListAllModelsForAllProvidersQueryKey, + v1ListWorkspacesByProviderQueryKey, ]) }, [queryClient]) diff --git a/src/features/providers/hooks/use-query-workspaces-by-provider.ts b/src/features/providers/hooks/use-query-workspaces-by-provider.ts new file mode 100644 index 00000000..ef3484a1 --- /dev/null +++ b/src/features/providers/hooks/use-query-workspaces-by-provider.ts @@ -0,0 +1,16 @@ +import { v1ListWorkspacesByProviderOptions } from '@/api/generated/@tanstack/react-query.gen' +import { useQuery } from '@tanstack/react-query' + +export function useQueryWorkspacesByProvider( + providerId: string | undefined | null +) { + if (!providerId) { + throw new Error('providerId is required') + } + + return useQuery({ + ...v1ListWorkspacesByProviderOptions({ path: { provider_id: providerId } }), + // eslint-disable-next-line no-restricted-syntax + refetchOnMount: true, + }) +} diff --git a/src/features/workspace/hooks/use-invalidate-workspace-queries.ts b/src/features/workspace/hooks/use-invalidate-workspace-queries.ts index 277db5b4..58957dc6 100644 --- a/src/features/workspace/hooks/use-invalidate-workspace-queries.ts +++ b/src/features/workspace/hooks/use-invalidate-workspace-queries.ts @@ -1,5 +1,7 @@ import { + v1GetWorkspaceMuxesQueryKey, v1ListArchivedWorkspacesQueryKey, + v1ListWorkspacesByProviderQueryKey, v1ListWorkspacesQueryKey, } from '@/api/generated/@tanstack/react-query.gen' import { invalidateQueries } from '@/lib/react-query-utils' @@ -13,6 +15,8 @@ export function useInvalidateWorkspaceQueries() { invalidateQueries(queryClient, [ v1ListWorkspacesQueryKey, v1ListArchivedWorkspacesQueryKey, + v1GetWorkspaceMuxesQueryKey, + v1ListWorkspacesByProviderQueryKey, ]) }, [queryClient]) diff --git a/src/lib/is-alert-pii.ts b/src/lib/is-alert-pii.ts new file mode 100644 index 00000000..aa1d5ea9 --- /dev/null +++ b/src/lib/is-alert-pii.ts @@ -0,0 +1,14 @@ +import { Alert, AlertConversation, Conversation } from '@/api/generated' + +export function isConversationWithPII( + conversation: Conversation | null +): boolean { + return conversation?.alerts?.some(isAlertPii) ?? false +} + +export function isAlertPii(alert: Alert | AlertConversation | null) { + return ( + alert?.trigger_category === 'critical' && + alert.trigger_type === 'codegate-pii' + ) +} diff --git a/src/mocks/msw/mockers/alert.mock.ts b/src/mocks/msw/mockers/alert.mock.ts index e8a4e262..91768414 100644 --- a/src/mocks/msw/mockers/alert.mock.ts +++ b/src/mocks/msw/mockers/alert.mock.ts @@ -1,11 +1,16 @@ -import { Alert, AlertSeverity } from "@/api/generated"; -import { faker } from "@faker-js/faker"; +import { Alert, AlertSeverity } from '@/api/generated' +import { faker } from '@faker-js/faker' const ALERT_SECRET_FIELDS = { trigger_string: 'foo', trigger_type: 'codegate-secrets', } satisfies Pick +const ALERT_PII_FIELDS = { + trigger_string: 'fakemail@fakedomain.mock', + trigger_type: 'codegate-pii', +} satisfies Pick + const ALERT_MALICIOUS_FIELDS = { trigger_string: { name: 'invokehttp', @@ -31,7 +36,7 @@ const getBaseAlert = ({ export const mockAlert = ({ type, }: { - type: 'secret' | 'malicious' + type: 'secret' | 'malicious' | 'pii' }): Alert => { const timestamp = faker.date.recent().toISOString() @@ -54,6 +59,14 @@ export const mockAlert = ({ ...ALERT_SECRET_FIELDS, } + return result + } + case 'pii': { + const result: Alert = { + ...base, + ...ALERT_PII_FIELDS, + } + return result } } diff --git a/src/mocks/msw/mockers/conversation.mock.ts b/src/mocks/msw/mockers/conversation.mock.ts index 11c10862..88879b08 100644 --- a/src/mocks/msw/mockers/conversation.mock.ts +++ b/src/mocks/msw/mockers/conversation.mock.ts @@ -12,7 +12,7 @@ export function mockConversation({ withTokenUsage?: boolean alertsConfig?: { numAlerts?: number - type?: 'secret' | 'malicious' | 'any' + type?: 'secret' | 'malicious' | 'any' | 'pii' } } = {}) { const timestamp = faker.date.recent().toISOString() pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy