diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 075f2a6f..d416ed88 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -73,4 +73,5 @@ jobs: cache: pnpm cache-dependency-path: ui/web/pnpm-lock.yaml - run: pnpm install --frozen-lockfile + - run: pnpm lint - run: pnpm build diff --git a/ui/web/eslint.config.js b/ui/web/eslint.config.js new file mode 100644 index 00000000..7a063185 --- /dev/null +++ b/ui/web/eslint.config.js @@ -0,0 +1,37 @@ +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import tseslint from "typescript-eslint"; + +export default tseslint.config( + { ignores: ["dist", "node_modules"] }, + { + extends: [js.configs.recommended, ...tseslint.configs.recommended], + files: ["**/*.{ts,tsx}"], + languageOptions: { + ecmaVersion: 2024, + globals: globals.browser, + }, + plugins: { + "react-hooks": reactHooks, + "react-refresh": reactRefresh, + }, + rules: { + // React hooks - keep critical rules only + "react-hooks/rules-of-hooks": "error", + // Disabled: many intentional patterns (stable refs, translation fn) + "react-hooks/exhaustive-deps": "off", + // Disabled: legitimate pattern to co-locate hooks with components + "react-refresh/only-export-components": "off", + + // TypeScript + "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }], + // Disabled: pragmatic casts for external libs and dynamic data + "@typescript-eslint/no-explicit-any": "off", + + // General - disabled for dev convenience + "no-console": "off", + }, + } +); diff --git a/ui/web/package.json b/ui/web/package.json index 9e5655b3..591598ae 100644 --- a/ui/web/package.json +++ b/ui/web/package.json @@ -8,6 +8,7 @@ "build": "tsc -b && vite build", "preview": "vite preview", "lint": "eslint .", + "lint:fix": "eslint . --fix", "test": "vitest run", "test:watch": "vitest", "test:ui": "vitest --ui" @@ -54,6 +55,7 @@ "zustand": "^5.0.12" }, "devDependencies": { + "@eslint/js": "^10.0.1", "@tailwindcss/vite": "^4.2.2", "@types/mdast": "^4.0.4", "@types/react": "^19.2.14", @@ -61,9 +63,14 @@ "@types/ws": "^8.18.1", "@vitejs/plugin-react": "^6.0.1", "@vitest/ui": "^4.1.4", + "eslint": "^10.2.0", + "eslint-plugin-react-hooks": "^7.0.1", + "eslint-plugin-react-refresh": "^0.5.2", + "globals": "^17.5.0", "jsdom": "^29.0.2", "tailwindcss": "^4.2.2", "typescript": "^6.0.2", + "typescript-eslint": "^8.58.1", "unified": "^11.0.5", "vite": "^8.0.8", "vitest": "^4.1.4", diff --git a/ui/web/pnpm-lock.yaml b/ui/web/pnpm-lock.yaml index 678b0a0a..3e8e14b8 100644 --- a/ui/web/pnpm-lock.yaml +++ b/ui/web/pnpm-lock.yaml @@ -126,6 +126,9 @@ importers: specifier: ^5.0.12 version: 5.0.12(@types/react@19.2.14)(immer@11.1.4)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)) devDependencies: + '@eslint/js': + specifier: ^10.0.1 + version: 10.0.1(eslint@10.2.0(jiti@2.6.1)) '@tailwindcss/vite': specifier: ^4.2.2 version: 4.2.2(vite@8.0.8(@types/node@25.5.0)(jiti@2.6.1)) @@ -147,6 +150,18 @@ importers: '@vitest/ui': specifier: ^4.1.4 version: 4.1.4(vitest@4.1.4) + eslint: + specifier: ^10.2.0 + version: 10.2.0(jiti@2.6.1) + eslint-plugin-react-hooks: + specifier: ^7.0.1 + version: 7.0.1(eslint@10.2.0(jiti@2.6.1)) + eslint-plugin-react-refresh: + specifier: ^0.5.2 + version: 0.5.2(eslint@10.2.0(jiti@2.6.1)) + globals: + specifier: ^17.5.0 + version: 17.5.0 jsdom: specifier: ^29.0.2 version: 29.0.2 @@ -156,6 +171,9 @@ importers: typescript: specifier: ^6.0.2 version: 6.0.2 + typescript-eslint: + specifier: ^8.58.1 + version: 8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) unified: specifier: ^11.0.5 version: 11.0.5 @@ -185,10 +203,77 @@ packages: '@asamuzakjp/nwsapi@2.3.9': resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/runtime@7.29.2': resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} engines: {node: '>=6.9.0'} + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + '@braintree/sanitize-url@7.1.2': resolution: {integrity: sha512-jigsZK+sMF/cuiB7sERuo9V7N9jx+dhmHHnQyDSVdpZwVutaBu7WvNYqMDLSgFgfB30n452TP3vjDAvFC973mA==} @@ -278,6 +363,45 @@ packages: '@emnapi/wasi-threads@1.2.1': resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.23.5': + resolution: {integrity: sha512-Y3kKLvC1dvTOT+oGlqNQ1XLqK6D1HU2YXPc52NmAlJZbMMWDzGYXMiPRJ8TYD39muD/OTjlZmNJ4ib7dvSrMBA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/config-helpers@0.5.5': + resolution: {integrity: sha512-eIJYKTCECbP/nsKaaruF6LW967mtbQbsw4JTtSVkUQc9MneSkbrgPJAbKl9nWr0ZeowV8BfsarBmPpBzGelA2w==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/core@1.2.1': + resolution: {integrity: sha512-MwcE1P+AZ4C6DWlpin/OmOA54mmIZ/+xZuJiQd4SyB29oAJjN30UW9wkKNptW2ctp4cEsvhlLY/CsQ1uoHDloQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/js@10.0.1': + resolution: {integrity: sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + peerDependencies: + eslint: ^10.0.0 + peerDependenciesMeta: + eslint: + optional: true + + '@eslint/object-schema@3.0.5': + resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + '@eslint/plugin-kit@0.7.1': + resolution: {integrity: sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + '@exodus/bytes@1.15.0': resolution: {integrity: sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -307,6 +431,22 @@ packages: peerDependencies: react-hook-form: ^7.55.0 + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -1380,6 +1520,9 @@ packages: '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/esrecurse@4.3.1': + resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} + '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} @@ -1392,6 +1535,9 @@ packages: '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + '@types/katex@0.16.8': resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} @@ -1427,6 +1573,65 @@ packages: '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + '@typescript-eslint/eslint-plugin@8.58.1': + resolution: {integrity: sha512-eSkwoemjo76bdXl2MYqtxg51HNwUSkWfODUOQ3PaTLZGh9uIWWFZIjyjaJnex7wXDu+TRx+ATsnSxdN9YWfRTQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.58.1 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.58.1': + resolution: {integrity: sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.58.1': + resolution: {integrity: sha512-gfQ8fk6cxhtptek+/8ZIqw8YrRW5048Gug8Ts5IYcMLCw18iUgrZAEY/D7s4hkI0FxEfGakKuPK/XUMPzPxi5g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.58.1': + resolution: {integrity: sha512-TPYUEqJK6avLcEjumWsIuTpuYODTTDAtoMdt8ZZa93uWMTX13Nb8L5leSje1NluammvU+oI3QRr5lLXPgihX3w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.58.1': + resolution: {integrity: sha512-JAr2hOIct2Q+qk3G+8YFfqkqi7sC86uNryT+2i5HzMa2MPjw4qNFvtjnw1IiA1rP7QhNKVe21mSSLaSjwA1Olw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.58.1': + resolution: {integrity: sha512-HUFxvTJVroT+0rXVJC7eD5zol6ID+Sn5npVPWoFuHGg9Ncq5Q4EYstqR+UOqaNRFXi5TYkpXXkLhoCHe3G0+7w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.58.1': + resolution: {integrity: sha512-io/dV5Aw5ezwzfPBBWLoT+5QfVtP8O7q4Kftjn5azJ88bYyp/ZMCsyW1lpKK46EXJcaYMZ1JtYj+s/7TdzmQMw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.58.1': + resolution: {integrity: sha512-w4w7WR7GHOjqqPnvAYbazq+Y5oS68b9CzasGtnd6jIeOIeKUzYzupGTB2T4LTPSv4d+WPeccbxuneTFHYgAAWg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.58.1': + resolution: {integrity: sha512-Ln8R0tmWC7pTtLOzgJzYTXSCjJ9rDNHAqTaVONF4FEi2qwce8mD9iSOxOpLFFvWp/wBFlew0mjM1L1ihYWfBdQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.58.1': + resolution: {integrity: sha512-y+vH7QE8ycjoa0bWciFg7OpFcipUuem1ujhrdLtq1gByKwfbC7bPeKsiny9e0urg93DqwGcHey+bGRKCnF1nZQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} @@ -1480,11 +1685,19 @@ packages: '@vitest/utils@4.1.4': resolution: {integrity: sha512-13QMT+eysM5uVGa1rG4kegGYNp6cnQcsTc67ELFbhNLQO+vgsygtYJx2khvdt4gVQqSSpC/KT5FZZxUpP3Oatw==} + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + acorn@8.16.0: resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} engines: {node: '>=0.4.0'} hasBin: true + ajv@6.14.0: + resolution: {integrity: sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==} + aria-hidden@1.2.6: resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} engines: {node: '>=10'} @@ -1496,9 +1709,30 @@ packages: bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + baseline-browser-mapping@2.10.18: + resolution: {integrity: sha512-VSnGQAOLtP5mib/DPyg2/t+Tlv65NTBz83BJBJvmLVHHuKJVaDOBvJJykiT5TR++em5nfAySPccDZDa4oSrn8A==} + engines: {node: '>=6.0.0'} + hasBin: true + bidi-js@1.0.3: resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + engines: {node: 18 || 20 || >=22} + + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + caniuse-lite@1.0.30001787: + resolution: {integrity: sha512-mNcrMN9KeI68u7muanUpEejSLghOKlVhRqS/Za2IeyGllJ9I9otGpR9g3nsw7n4W378TE/LyIteA0+/FOZm4Kg==} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1564,6 +1798,10 @@ packages: cose-base@2.2.0: resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + css-tree@3.2.1: resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} @@ -1760,6 +1998,9 @@ packages: decode-named-character-reference@1.3.0: resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + delaunator@5.1.0: resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} @@ -1780,6 +2021,9 @@ packages: dompurify@3.3.3: resolution: {integrity: sha512-Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA==} + electron-to-chromium@1.5.335: + resolution: {integrity: sha512-q9n5T4BR4Xwa2cwbrwcsDJtHD/enpQ5S1xF1IAtdqf5AAgqDFmR/aakqH3ChFdqd/QXJhS3rnnXFtexU7rax6Q==} + enhanced-resolve@5.20.1: resolution: {integrity: sha512-Qohcme7V1inbAfvjItgw0EaxVX5q2rdVEZHRBrEQdRZTssLDGsL8Lwrznl8oQ/6kuTJONLaDcGjkNP247XEhcA==} engines: {node: '>=10.13.0'} @@ -1794,16 +2038,77 @@ packages: es-toolkit@1.45.1: resolution: {integrity: sha512-/jhoOj/Fx+A+IIyDNOvO3TItGmlMKhtX8ISAHKE90c4b/k1tqaqEZ+uUqfpU8DMnW5cgNJv606zS55jGvza0Xw==} + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + escape-string-regexp@5.0.0: resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} engines: {node: '>=12'} + eslint-plugin-react-hooks@7.0.1: + resolution: {integrity: sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==} + engines: {node: '>=18'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-refresh@0.5.2: + resolution: {integrity: sha512-hmgTH57GfzoTFjVN0yBwTggnsVUF2tcqi7RJZHqi9lIezSs4eFyAMktA68YD4r5kNw1mxyY4dmkyoFDb3FIqrA==} + peerDependencies: + eslint: ^9 || ^10 + + eslint-scope@9.1.2: + resolution: {integrity: sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@10.2.0: + resolution: {integrity: sha512-+L0vBFYGIpSNIt/KWTpFonPrqYvgKw1eUI5Vn7mEogrQcWtWYtNQ7dNqC+px/J0idT3BAkiWrhfS7k+Tum8TUA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@11.2.0: + resolution: {integrity: sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + estree-util-is-identifier-name@3.0.0: resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + eventemitter3@5.0.4: resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} @@ -1818,6 +2123,15 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -1830,6 +2144,18 @@ packages: fflate@0.8.2: resolution: {integrity: sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==} + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + flatted@3.4.2: resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} @@ -1852,10 +2178,22 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + get-nonce@1.0.1: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@17.5.0: + resolution: {integrity: sha512-qoV+HK2yFl/366t2/Cb3+xxPUo5BuMynomoDmiaZBIdbs+0pYbjfZU+twLhGKp4uCZ/+NbtpVepH5bGCxRyy2g==} + engines: {node: '>=18'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -1920,6 +2258,12 @@ packages: hastscript@9.0.1: resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + hermes-estree@0.25.1: + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} + + hermes-parser@0.25.1: + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + highlight.js@11.11.1: resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} engines: {node: '>=12.0.0'} @@ -1946,6 +2290,14 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + immediate@3.0.6: resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} @@ -1955,6 +2307,10 @@ packages: immer@11.1.4: resolution: {integrity: sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw==} + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -1977,6 +2333,14 @@ packages: is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + is-hexadecimal@2.0.1: resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} @@ -1990,10 +2354,16 @@ packages: isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + jsdom@29.0.2: resolution: {integrity: sha512-9VnGEBosc/ZpwyOsJBCQ/3I5p7Q5ngOY14a9bf5btenAORmZfDse1ZEheMiWcJ3h81+Fv7HmJFdS0szo/waF2w==} engines: {node: ^20.19.0 || ^22.13.0 || >=24.0.0} @@ -2003,6 +2373,25 @@ packages: canvas: optional: true + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + jszip@3.10.1: resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} @@ -2010,6 +2399,9 @@ packages: resolution: {integrity: sha512-pQpZbdBu7wCTmQUh7ufPmLr0pFoObnGUoL/yhtwJDgmmQpbkg/0HSVti25Fu4rmd1oCR6NGWe9vqTWuWv3GcNA==} hasBin: true + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + khroma@2.1.0: resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} @@ -2023,6 +2415,10 @@ packages: layout-base@2.0.1: resolution: {integrity: sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==} + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + lie@3.3.0: resolution: {integrity: sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==} @@ -2100,6 +2496,10 @@ packages: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + lodash-es@4.18.1: resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} @@ -2113,6 +2513,9 @@ packages: resolution: {integrity: sha512-JvNw9Y81y33E+BEYPr0U7omo+U9AySnsMsEiXgwT6yqd31VQWTLNQqmT4ou5eqPFUrTfIDFta2wKhB1hyohtAQ==} engines: {node: 20 || >=22} + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + lucide-react@1.7.0: resolution: {integrity: sha512-yI7BeItCLZJTXikmK4KNUGCKoGzSvbKlfCvw44bU4fXAL6v3gYS4uHD1jzsLkfwODYwI6Drw5Tu9Z5ulDe0TSg==} peerDependencies: @@ -2270,6 +2673,10 @@ packages: micromark@4.0.2: resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + mlly@1.8.2: resolution: {integrity: sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==} @@ -2294,12 +2701,30 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + node-releases@2.0.37: + resolution: {integrity: sha512-1h5gKZCF+pO/o3Iqt5Jp7wc9rH3eJJ0+nh/CIoiRwjRxde/hAHyLPXYN4V3CqKAbiZPSeJFSWHmJsbkicta0Eg==} + obliterator@2.0.5: resolution: {integrity: sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==} obug@2.1.1: resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + package-manager-detector@1.6.0: resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} @@ -2321,6 +2746,14 @@ packages: path-data-parser@0.1.0: resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==} + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -2348,6 +2781,10 @@ packages: resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==} engines: {node: ^10 || ^12 || >=14} + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -2537,12 +2974,29 @@ packages: scheduler@0.27.0: resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + set-cookie-parser@2.7.2: resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} setimmediate@1.0.5: resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -2637,6 +3091,12 @@ packages: trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + ts-dedent@2.2.0: resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} engines: {node: '>=6.10'} @@ -2644,6 +3104,17 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typescript-eslint@8.58.1: + resolution: {integrity: sha512-gf6/oHChByg9HJvhMO1iBexJh12AqqTfnuxscMDOVqfJW3htsdRJI/GfPpHTTcyeB8cSTUY2JcZmVgoyPqcrDg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + typescript@6.0.2: resolution: {integrity: sha512-bGdAIrZ0wiGDo5l8c++HWtbaNCWTS4UTv7RaTH/ThVIgjkveJt83m74bBHMJkuCbslY8ixgLBVZJIOiQlQTjfQ==} engines: {node: '>=14.17'} @@ -2683,6 +3154,15 @@ packages: unist-util-visit@5.1.0: resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + use-callback-ref@1.3.3: resolution: {integrity: sha512-jQL3lRnocaFtu3V00JToYz/4QkNWswxijDaCVNZRiRTO3HQDLsdu1ZtmIUvV4yPp+rvWm5j0y0TG/S61cuijTg==} engines: {node: '>=10'} @@ -2854,11 +3334,20 @@ packages: resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + why-is-node-running@2.3.0: resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} hasBin: true + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + ws@8.20.0: resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} engines: {node: '>=10.0.0'} @@ -2878,6 +3367,19 @@ packages: xmlchars@2.2.0: resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zod-validation-error@4.0.2: + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + zod@4.3.6: resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} @@ -2925,8 +3427,108 @@ snapshots: '@asamuzakjp/nwsapi@2.3.9': {} + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + '@babel/runtime@7.29.2': {} + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + '@braintree/sanitize-url@7.1.2': {} '@bramus/specificity@2.4.2': @@ -3013,6 +3615,40 @@ snapshots: tslib: 2.8.1 optional: true + '@eslint-community/eslint-utils@4.9.1(eslint@10.2.0(jiti@2.6.1))': + dependencies: + eslint: 10.2.0(jiti@2.6.1) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.23.5': + dependencies: + '@eslint/object-schema': 3.0.5 + debug: 4.4.3 + minimatch: 10.2.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.5.5': + dependencies: + '@eslint/core': 1.2.1 + + '@eslint/core@1.2.1': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/js@10.0.1(eslint@10.2.0(jiti@2.6.1))': + optionalDependencies: + eslint: 10.2.0(jiti@2.6.1) + + '@eslint/object-schema@3.0.5': {} + + '@eslint/plugin-kit@0.7.1': + dependencies: + '@eslint/core': 1.2.1 + levn: 0.4.1 + '@exodus/bytes@1.15.0': {} '@floating-ui/core@1.7.5': @@ -3037,6 +3673,17 @@ snapshots: '@standard-schema/utils': 0.3.0 react-hook-form: 7.72.1(react@19.2.4) + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.7': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.4.3 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + '@iconify/types@2.0.0': {} '@iconify/utils@3.1.0': @@ -4120,6 +4767,8 @@ snapshots: '@types/deep-eql@4.0.2': {} + '@types/esrecurse@4.3.1': {} + '@types/estree-jsx@1.0.5': dependencies: '@types/estree': 1.0.8 @@ -4132,6 +4781,8 @@ snapshots: dependencies: '@types/unist': 3.0.3 + '@types/json-schema@7.0.15': {} + '@types/katex@0.16.8': {} '@types/mdast@4.0.4': @@ -4165,6 +4816,97 @@ snapshots: dependencies: '@types/node': 25.5.0 + '@typescript-eslint/eslint-plugin@8.58.1(@typescript-eslint/parser@8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2))(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/scope-manager': 8.58.1 + '@typescript-eslint/type-utils': 8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/utils': 8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/visitor-keys': 8.58.1 + eslint: 10.2.0(jiti@2.6.1) + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@6.0.2) + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2)': + dependencies: + '@typescript-eslint/scope-manager': 8.58.1 + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/typescript-estree': 8.58.1(typescript@6.0.2) + '@typescript-eslint/visitor-keys': 8.58.1 + debug: 4.4.3 + eslint: 10.2.0(jiti@2.6.1) + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.58.1(typescript@6.0.2)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.58.1(typescript@6.0.2) + '@typescript-eslint/types': 8.58.1 + debug: 4.4.3 + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.58.1': + dependencies: + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/visitor-keys': 8.58.1 + + '@typescript-eslint/tsconfig-utils@8.58.1(typescript@6.0.2)': + dependencies: + typescript: 6.0.2 + + '@typescript-eslint/type-utils@8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2)': + dependencies: + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/typescript-estree': 8.58.1(typescript@6.0.2) + '@typescript-eslint/utils': 8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) + debug: 4.4.3 + eslint: 10.2.0(jiti@2.6.1) + ts-api-utils: 2.5.0(typescript@6.0.2) + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.58.1': {} + + '@typescript-eslint/typescript-estree@8.58.1(typescript@6.0.2)': + dependencies: + '@typescript-eslint/project-service': 8.58.1(typescript@6.0.2) + '@typescript-eslint/tsconfig-utils': 8.58.1(typescript@6.0.2) + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/visitor-keys': 8.58.1 + debug: 4.4.3 + minimatch: 10.2.5 + semver: 7.7.4 + tinyglobby: 0.2.16 + ts-api-utils: 2.5.0(typescript@6.0.2) + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@10.2.0(jiti@2.6.1)) + '@typescript-eslint/scope-manager': 8.58.1 + '@typescript-eslint/types': 8.58.1 + '@typescript-eslint/typescript-estree': 8.58.1(typescript@6.0.2) + eslint: 10.2.0(jiti@2.6.1) + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.58.1': + dependencies: + '@typescript-eslint/types': 8.58.1 + eslint-visitor-keys: 5.0.1 + '@ungap/structured-clone@1.3.0': {} '@upsetjs/venn.js@2.0.0': @@ -4229,8 +4971,19 @@ snapshots: convert-source-map: 2.0.0 tinyrainbow: 3.1.0 + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + acorn@8.16.0: {} + ajv@6.14.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + aria-hidden@1.2.6: dependencies: tslib: 2.8.1 @@ -4239,10 +4992,28 @@ snapshots: bail@2.0.2: {} + balanced-match@4.0.4: {} + + baseline-browser-mapping@2.10.18: {} + bidi-js@1.0.3: dependencies: require-from-string: 2.0.2 + brace-expansion@5.0.5: + dependencies: + balanced-match: 4.0.4 + + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.18 + caniuse-lite: 1.0.30001787 + electron-to-chromium: 1.5.335 + node-releases: 2.0.37 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + + caniuse-lite@1.0.30001787: {} + ccount@2.0.1: {} chai@6.2.2: {} @@ -4296,6 +5067,12 @@ snapshots: dependencies: layout-base: 2.0.1 + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + css-tree@3.2.1: dependencies: mdn-data: 2.27.1 @@ -4512,6 +5289,8 @@ snapshots: dependencies: character-entities: 2.0.2 + deep-is@0.1.4: {} + delaunator@5.1.0: dependencies: robust-predicates: 3.0.3 @@ -4530,6 +5309,8 @@ snapshots: optionalDependencies: '@types/trusted-types': 2.0.7 + electron-to-chromium@1.5.335: {} + enhanced-resolve@5.20.1: dependencies: graceful-fs: 4.2.11 @@ -4541,14 +5322,99 @@ snapshots: es-toolkit@1.45.1: {} + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + escape-string-regexp@5.0.0: {} + eslint-plugin-react-hooks@7.0.1(eslint@10.2.0(jiti@2.6.1)): + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.2 + eslint: 10.2.0(jiti@2.6.1) + hermes-parser: 0.25.1 + zod: 4.3.6 + zod-validation-error: 4.0.2(zod@4.3.6) + transitivePeerDependencies: + - supports-color + + eslint-plugin-react-refresh@0.5.2(eslint@10.2.0(jiti@2.6.1)): + dependencies: + eslint: 10.2.0(jiti@2.6.1) + + eslint-scope@9.1.2: + dependencies: + '@types/esrecurse': 4.3.1 + '@types/estree': 1.0.8 + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@10.2.0(jiti@2.6.1): + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@10.2.0(jiti@2.6.1)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.23.5 + '@eslint/config-helpers': 0.5.5 + '@eslint/core': 1.2.1 + '@eslint/plugin-kit': 0.7.1 + '@humanfs/node': 0.16.7 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.14.0 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 9.1.2 + eslint-visitor-keys: 5.0.1 + espree: 11.2.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + minimatch: 10.2.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.6.1 + transitivePeerDependencies: + - supports-color + + espree@11.2.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 5.0.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + estree-util-is-identifier-name@3.0.0: {} estree-walker@3.0.3: dependencies: '@types/estree': 1.0.8 + esutils@2.0.3: {} + eventemitter3@5.0.4: {} events@3.3.0: {} @@ -4557,12 +5423,32 @@ snapshots: extend@3.0.2: {} + fast-deep-equal@3.1.3: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + fdir@6.5.0(picomatch@4.0.4): optionalDependencies: picomatch: 4.0.4 fflate@0.8.2: {} + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + flatted@3.4.2: {} framer-motion@12.38.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4): @@ -4577,8 +5463,16 @@ snapshots: fsevents@2.3.3: optional: true + gensync@1.0.0-beta.2: {} + get-nonce@1.0.1: {} + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@17.5.0: {} + graceful-fs@4.2.11: {} graphology-layout-forceatlas2@0.10.1(graphology-types@0.24.8): @@ -4690,6 +5584,12 @@ snapshots: property-information: 7.1.0 space-separated-tokens: 2.0.2 + hermes-estree@0.25.1: {} + + hermes-parser@0.25.1: + dependencies: + hermes-estree: 0.25.1 + highlight.js@11.11.1: {} html-encoding-sniffer@6.0.0: @@ -4714,12 +5614,18 @@ snapshots: dependencies: safer-buffer: 2.1.2 + ignore@5.3.2: {} + + ignore@7.0.5: {} + immediate@3.0.6: {} immer@10.2.0: {} immer@11.1.4: {} + imurmurhash@0.1.4: {} + inherits@2.0.4: {} inline-style-parser@0.2.7: {} @@ -4737,6 +5643,12 @@ snapshots: is-decimal@2.0.1: {} + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + is-hexadecimal@2.0.1: {} is-plain-obj@4.1.0: {} @@ -4745,8 +5657,12 @@ snapshots: isarray@1.0.0: {} + isexe@2.0.0: {} + jiti@2.6.1: {} + js-tokens@4.0.0: {} + jsdom@29.0.2: dependencies: '@asamuzakjp/css-color': 5.1.10 @@ -4773,6 +5689,16 @@ snapshots: transitivePeerDependencies: - '@noble/hashes' + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@2.2.3: {} + jszip@3.10.1: dependencies: lie: 3.3.0 @@ -4784,6 +5710,10 @@ snapshots: dependencies: commander: 8.3.0 + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + khroma@2.1.0: {} langium@4.2.2: @@ -4799,6 +5729,11 @@ snapshots: layout-base@2.0.1: {} + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + lie@3.3.0: dependencies: immediate: 3.0.6 @@ -4852,6 +5787,10 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + lodash-es@4.18.1: {} longest-streak@3.1.0: {} @@ -4864,6 +5803,10 @@ snapshots: lru-cache@11.3.3: {} + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + lucide-react@1.7.0(react@19.2.4): dependencies: react: 19.2.4 @@ -5268,6 +6211,10 @@ snapshots: transitivePeerDependencies: - supports-color + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.5 + mlly@1.8.2: dependencies: acorn: 8.16.0 @@ -5291,10 +6238,31 @@ snapshots: nanoid@3.3.11: {} + natural-compare@1.4.0: {} + + node-releases@2.0.37: {} + obliterator@2.0.5: {} obug@2.1.1: {} + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + package-manager-detector@1.6.0: {} pako@1.0.11: {} @@ -5323,6 +6291,10 @@ snapshots: path-data-parser@0.1.0: {} + path-exists@4.0.0: {} + + path-key@3.1.1: {} + pathe@2.0.3: {} picocolors@1.1.1: {} @@ -5353,6 +6325,8 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + prelude-ls@1.2.1: {} + process-nextick-args@2.0.1: {} property-information@7.1.0: {} @@ -5651,10 +6625,20 @@ snapshots: scheduler@0.27.0: {} + semver@6.3.1: {} + + semver@7.7.4: {} + set-cookie-parser@2.7.2: {} setimmediate@1.0.5: {} + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + siginfo@2.0.0: {} sigma@3.0.2(graphology-types@0.24.8): @@ -5738,10 +6722,29 @@ snapshots: trough@2.2.0: {} + ts-api-utils@2.5.0(typescript@6.0.2): + dependencies: + typescript: 6.0.2 + ts-dedent@2.2.0: {} tslib@2.8.1: {} + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typescript-eslint@8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2): + dependencies: + '@typescript-eslint/eslint-plugin': 8.58.1(@typescript-eslint/parser@8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2))(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/parser': 8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) + '@typescript-eslint/typescript-estree': 8.58.1(typescript@6.0.2) + '@typescript-eslint/utils': 8.58.1(eslint@10.2.0(jiti@2.6.1))(typescript@6.0.2) + eslint: 10.2.0(jiti@2.6.1) + typescript: 6.0.2 + transitivePeerDependencies: + - supports-color + typescript@6.0.2: {} ufo@1.6.3: {} @@ -5793,6 +6796,16 @@ snapshots: unist-util-is: 6.0.1 unist-util-visit-parents: 6.0.2 + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + use-callback-ref@1.3.3(@types/react@19.2.14)(react@19.2.4): dependencies: react: 19.2.4 @@ -5926,17 +6939,31 @@ snapshots: transitivePeerDependencies: - '@noble/hashes' + which@2.0.2: + dependencies: + isexe: 2.0.0 + why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 stackback: 0.0.2 + word-wrap@1.2.5: {} + ws@8.20.0: {} xml-name-validator@5.0.0: {} xmlchars@2.2.0: {} + yallist@3.1.1: {} + + yocto-queue@0.1.0: {} + + zod-validation-error@4.0.2(zod@4.3.6): + dependencies: + zod: 4.3.6 + zod@4.3.6: {} zustand@5.0.12(@types/react@19.2.14)(immer@11.1.4)(react@19.2.4)(use-sync-external-store@1.6.0(react@19.2.4)): diff --git a/ui/web/src/components/graph/sigma-graph-container.tsx b/ui/web/src/components/graph/sigma-graph-container.tsx index 1731a217..e338c821 100644 --- a/ui/web/src/components/graph/sigma-graph-container.tsx +++ b/ui/web/src/components/graph/sigma-graph-container.tsx @@ -164,7 +164,7 @@ export function SigmaGraphContainer({ onSigmaReady?.(null); } }; - }, [graph, edgeType, compact]); // eslint-disable-line react-hooks/exhaustive-deps + }, [graph, edgeType, compact]); // --- Update theme colors without re-init --- useEffect(() => { diff --git a/ui/web/src/components/providers/ws-provider.tsx b/ui/web/src/components/providers/ws-provider.tsx index d3672629..3b407d91 100644 --- a/ui/web/src/components/providers/ws-provider.tsx +++ b/ui/web/src/components/providers/ws-provider.tsx @@ -53,14 +53,14 @@ export function WsProvider({ children }: { children: React.ReactNode }) { store.setTenantSelected(true); } else if (!client.isOwner && tenants.length === 1) { // Non-owner with single tenant — auto-select - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + localStorage.setItem(LOCAL_STORAGE_KEYS.TENANT_ID, tenants[0]!.slug); store.setTenantSelected(true); } else if (!client.isOwner && tenants.length === 0) { // No tenants — leave tenantSelected=false (blocked) } else if (client.isOwner && !savedScope && tenants.length > 0) { // Owner without scope — auto-select first tenant - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + localStorage.setItem(LOCAL_STORAGE_KEYS.TENANT_ID, tenants[0]!.slug); window.location.reload(); return; diff --git a/ui/web/src/components/shared/markdown-mermaid-block.tsx b/ui/web/src/components/shared/markdown-mermaid-block.tsx index 19c2d78c..83603b6f 100644 --- a/ui/web/src/components/shared/markdown-mermaid-block.tsx +++ b/ui/web/src/components/shared/markdown-mermaid-block.tsx @@ -83,7 +83,6 @@ export function MermaidBlock({ code }: MermaidBlockProps) { return (
); diff --git a/ui/web/src/components/shared/markdown-renderer.tsx b/ui/web/src/components/shared/markdown-renderer.tsx index 01241a85..c59f8d98 100644 --- a/ui/web/src/components/shared/markdown-renderer.tsx +++ b/ui/web/src/components/shared/markdown-renderer.tsx @@ -108,7 +108,7 @@ export const MarkdownRenderer = memo(function MarkdownRenderer({ content, classN }, []); // Stable components config — only recreated when token/callbacks change. - // eslint-disable-next-line @typescript-eslint/no-explicit-any + const components = useMemo((): Components & Record => ({ pre({ children }) { return <>{children}; diff --git a/ui/web/src/components/ui/combobox.tsx b/ui/web/src/components/ui/combobox.tsx index 369c5de0..4845ef85 100644 --- a/ui/web/src/components/ui/combobox.tsx +++ b/ui/web/src/components/ui/combobox.tsx @@ -83,7 +83,7 @@ export function Combobox({ // Auto-detect if inside a Radix Dialog (which sets pointer-events:none on body) const el = containerRef.current?.closest('[data-slot="dialog-content"]'); return el ?? null; - // eslint-disable-next-line react-hooks/exhaustive-deps + }, [portalContainer, open]); // Compute dropdown position — flip above input when near viewport bottom. diff --git a/ui/web/src/hooks/use-auto-scroll.ts b/ui/web/src/hooks/use-auto-scroll.ts index 3b476594..fdeab2ba 100644 --- a/ui/web/src/hooks/use-auto-scroll.ts +++ b/ui/web/src/hooks/use-auto-scroll.ts @@ -49,7 +49,7 @@ export function useAutoScroll( if (isNearBottom.current) { scrollToBottom(true); } - // eslint-disable-next-line react-hooks/exhaustive-deps + }, deps); // Force scroll when trigger increments (e.g. user sends a message) — instant diff --git a/ui/web/src/lib/timezone-utils.ts b/ui/web/src/lib/timezone-utils.ts index 0555176e..762fd717 100644 --- a/ui/web/src/lib/timezone-utils.ts +++ b/ui/web/src/lib/timezone-utils.ts @@ -45,7 +45,7 @@ export function getAllIanaTimezones(): TzOption[] { if (_cachedTimezones) return _cachedTimezones; let tzNames: string[]; try { - // eslint-disable-next-line @typescript-eslint/no-explicit-any + tzNames = (Intl as any).supportedValuesOf("timeZone") as string[]; } catch { tzNames = FALLBACK_TIMEZONES; diff --git a/ui/web/src/pages/agents/agent-detail/agent-advanced-dialog.tsx b/ui/web/src/pages/agents/agent-detail/agent-advanced-dialog.tsx index 1500b38a..5b70f486 100644 --- a/ui/web/src/pages/agents/agent-detail/agent-advanced-dialog.tsx +++ b/ui/web/src/pages/agents/agent-detail/agent-advanced-dialog.tsx @@ -78,7 +78,7 @@ export function AgentAdvancedDialog({ open, onOpenChange, agent, onUpdate }: Age setPrune(s.prune); setSbEnabled(s.sbEnabled); setSb(s.sb); - // eslint-disable-next-line react-hooks/exhaustive-deps + }, [open]); useEffect(() => { diff --git a/ui/web/src/pages/agents/agent-detail/file-sections/file-sidebar.tsx b/ui/web/src/pages/agents/agent-detail/file-sections/file-sidebar.tsx index b4ff1721..7265fee0 100644 --- a/ui/web/src/pages/agents/agent-detail/file-sections/file-sidebar.tsx +++ b/ui/web/src/pages/agents/agent-detail/file-sections/file-sidebar.tsx @@ -16,7 +16,7 @@ function estimateTokensFromContent(content: string): number { let ascii = 0; let nonAscii = 0; for (const ch of content) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + if (ch.codePointAt(0)! < 128) ascii++; else nonAscii++; } diff --git a/ui/web/src/pages/agents/agent-detail/heartbeat-config-dialog.tsx b/ui/web/src/pages/agents/agent-detail/heartbeat-config-dialog.tsx index 291306fe..044e53d4 100644 --- a/ui/web/src/pages/agents/agent-detail/heartbeat-config-dialog.tsx +++ b/ui/web/src/pages/agents/agent-detail/heartbeat-config-dialog.tsx @@ -158,7 +158,7 @@ export function HeartbeatConfigDialog({ loadChecklist(); fetchTargets().then(setTargets) .catch((err) => console.error("[HeartbeatConfig] fetch targets failed:", err)); - // eslint-disable-next-line react-hooks/exhaustive-deps + }, [open]); const handleTest = async () => { diff --git a/ui/web/src/pages/agents/agents-page.tsx b/ui/web/src/pages/agents/agents-page.tsx index 390ae6db..6f9ce2c7 100644 --- a/ui/web/src/pages/agents/agents-page.tsx +++ b/ui/web/src/pages/agents/agents-page.tsx @@ -46,6 +46,20 @@ export function AgentsPage() { const ownerIDs = useMemo(() => [...new Set(agents.map((a) => a.owner_id).filter(Boolean))], [agents]); const { resolve } = useContactResolver(ownerIDs); + const filtered = useMemo(() => agents.filter((a) => { + if (ownerFilter && a.owner_id !== ownerFilter) return false; + if (typeFilter && a.agent_type !== typeFilter) return false; + const q = search.toLowerCase(); + return ( + a.agent_key.toLowerCase().includes(q) || + (a.display_name ?? "").toLowerCase().includes(q) + ); + }), [agents, ownerFilter, typeFilter, search]); + + const { pageItems, pagination, setPage, setPageSize, resetPage } = usePagination(filtered); + + useEffect(() => { resetPage(); }, [search, ownerFilter, typeFilter, resetPage]); + const handleResummon = async (agent: { id: string; display_name?: string; agent_key: string }) => { try { await resummonAgent(agent.id); @@ -65,20 +79,6 @@ export function AgentsPage() { ); } - const filtered = agents.filter((a) => { - if (ownerFilter && a.owner_id !== ownerFilter) return false; - if (typeFilter && a.agent_type !== typeFilter) return false; - const q = search.toLowerCase(); - return ( - a.agent_key.toLowerCase().includes(q) || - (a.display_name ?? "").toLowerCase().includes(q) - ); - }); - - const { pageItems, pagination, setPage, setPageSize, resetPage } = usePagination(filtered); - - useEffect(() => { resetPage(); }, [search, ownerFilter, typeFilter, resetPage]); - const resolveOwnerName = (id: string) => { const contact = resolve(id); return contact?.display_name || contact?.username || id; diff --git a/ui/web/src/pages/api-keys/api-key-code-dialog.tsx b/ui/web/src/pages/api-keys/api-key-code-dialog.tsx index abb7557e..26a9340b 100644 --- a/ui/web/src/pages/api-keys/api-key-code-dialog.tsx +++ b/ui/web/src/pages/api-keys/api-key-code-dialog.tsx @@ -37,7 +37,7 @@ function highlightLine(line: string, lang: Tab): React.ReactNode | string { // Simple token-based highlighting const parts: React.ReactNode[] = []; - let remaining = line; + const remaining = line; let key = 0; const kwPatterns = lang === "go" @@ -67,7 +67,7 @@ function highlightLine(line: string, lang: Tab): React.ReactNode | string { // Remaining text after last string if (lastIndex < remaining.length) { const after = remaining.slice(lastIndex); - parts.push({highlightKeywords(after, kwPatterns)}); + parts.push({highlightKeywords(after, kwPatterns)}); } if (parts.length === 0) return line; diff --git a/ui/web/src/pages/builtin-tools/builtin-tool-row.tsx b/ui/web/src/pages/builtin-tools/builtin-tool-row.tsx index 232673ae..6b05fced 100644 --- a/ui/web/src/pages/builtin-tools/builtin-tool-row.tsx +++ b/ui/web/src/pages/builtin-tools/builtin-tool-row.tsx @@ -11,7 +11,7 @@ import { } from "@/components/ui/tooltip"; import type { BuiltinToolData } from "./hooks/use-builtin-tools"; -/* eslint-disable @typescript-eslint/no-explicit-any */ + // Tools with dedicated settings forms always show the Settings button, // even when settings is empty (the form lets the user create settings). diff --git a/ui/web/src/pages/builtin-tools/web-fetch-extractor-chain-form.tsx b/ui/web/src/pages/builtin-tools/web-fetch-extractor-chain-form.tsx index b0794929..0b007376 100644 --- a/ui/web/src/pages/builtin-tools/web-fetch-extractor-chain-form.tsx +++ b/ui/web/src/pages/builtin-tools/web-fetch-extractor-chain-form.tsx @@ -195,7 +195,7 @@ export function WebFetchExtractorChainForm({ initialSettings, onSave, onCancel } const handleSave = async () => { setSaving(true); try { - // eslint-disable-next-line @typescript-eslint/no-unused-vars + const serialized = entries.map(({ id: _id, ...rest }) => rest); await onSave({ extractors: serialized }); } catch { diff --git a/ui/web/src/pages/channels/channel-detail/channel-advanced-dialog.tsx b/ui/web/src/pages/channels/channel-detail/channel-advanced-dialog.tsx index 858e9312..3f9b19e2 100644 --- a/ui/web/src/pages/channels/channel-detail/channel-advanced-dialog.tsx +++ b/ui/web/src/pages/channels/channel-detail/channel-advanced-dialog.tsx @@ -42,10 +42,9 @@ function getAdvancedFields(channelType: string) { function deriveInitialValues(instance: ChannelInstanceData): Record { const config = (instance.config ?? {}) as Record; - const { groups: _groups, ...rest } = config as Record & { groups?: unknown }; // Only keep advanced keys (exclude essential + groups) return Object.fromEntries( - Object.entries(rest).filter(([k]) => !ESSENTIAL_CONFIG_KEYS.has(k)), + Object.entries(config).filter(([k]) => !ESSENTIAL_CONFIG_KEYS.has(k) && k !== "groups"), ); } @@ -65,7 +64,7 @@ export function ChannelAdvancedDialog({ useEffect(() => { if (!open) return; setValues(deriveInitialValues(instance)); - // eslint-disable-next-line react-hooks/exhaustive-deps + }, [open]); const handleChange = useCallback((key: string, value: unknown) => { diff --git a/ui/web/src/pages/channels/whatsapp/whatsapp-reauth-dialog.tsx b/ui/web/src/pages/channels/whatsapp/whatsapp-reauth-dialog.tsx index eb654748..1c25a260 100644 --- a/ui/web/src/pages/channels/whatsapp/whatsapp-reauth-dialog.tsx +++ b/ui/web/src/pages/channels/whatsapp/whatsapp-reauth-dialog.tsx @@ -30,7 +30,7 @@ export function WhatsAppReauthDialog({ // because we only want to trigger on open/close transitions, not on identity changes. useEffect(() => { if (open && status === "idle") start(); - }, [open]); // eslint-disable-line react-hooks/exhaustive-deps + }, [open]); // Reset state when dialog closes useEffect(() => { diff --git a/ui/web/src/pages/channels/zalo/zalo-personal-qr-dialog.tsx b/ui/web/src/pages/channels/zalo/zalo-personal-qr-dialog.tsx index d0cc1a9f..93b35ed6 100644 --- a/ui/web/src/pages/channels/zalo/zalo-personal-qr-dialog.tsx +++ b/ui/web/src/pages/channels/zalo/zalo-personal-qr-dialog.tsx @@ -30,7 +30,7 @@ export function ZaloPersonalQRDialog({ // Auto-start when dialog opens useEffect(() => { if (open && status === "idle") start(); - }, [open]); // eslint-disable-line react-hooks/exhaustive-deps + }, [open]); // Reset state when dialog closes useEffect(() => { diff --git a/ui/web/src/pages/chat/hooks/use-chat-team-tasks.ts b/ui/web/src/pages/chat/hooks/use-chat-team-tasks.ts index 8e5cbceb..f90b43da 100644 --- a/ui/web/src/pages/chat/hooks/use-chat-team-tasks.ts +++ b/ui/web/src/pages/chat/hooks/use-chat-team-tasks.ts @@ -91,8 +91,8 @@ export function useChatTeamTasks( eventName === "team.task.commented" || eventName === "team.task.attachment_added" ) { - let icon = "📋"; - let text = ""; + let icon: string; + let text: string; if (eventName === "team.task.completed") { icon = "✅"; text = `Task #${event.task_number} "${event.subject}" completed`; } else if (eventName === "team.task.failed") { icon = "❌"; text = `Task #${event.task_number} "${event.subject}" failed${event.reason ? ": " + event.reason : ""}`; } else if (eventName === "team.task.commented") { icon = "💬"; text = `Comment on #${event.task_number} "${event.subject}"`; } diff --git a/ui/web/src/pages/config/sections/ai-defaults-form-controls.tsx b/ui/web/src/pages/config/sections/ai-defaults-form-controls.tsx index f6785514..b75485a1 100644 --- a/ui/web/src/pages/config/sections/ai-defaults-form-controls.tsx +++ b/ui/web/src/pages/config/sections/ai-defaults-form-controls.tsx @@ -8,7 +8,7 @@ import { Label } from "@/components/ui/label"; import { Input } from "@/components/ui/input"; import { InfoLabel } from "@/components/shared/info-label"; -/* eslint-disable @typescript-eslint/no-explicit-any */ + export function SubSection({ title, diff --git a/ui/web/src/pages/config/sections/ai-defaults-section.tsx b/ui/web/src/pages/config/sections/ai-defaults-section.tsx index 0fa09830..815e3480 100644 --- a/ui/web/src/pages/config/sections/ai-defaults-section.tsx +++ b/ui/web/src/pages/config/sections/ai-defaults-section.tsx @@ -11,7 +11,7 @@ import { InfoLabel } from "@/components/shared/info-label"; import { ProviderModelSelect } from "@/components/shared/provider-model-select"; import { SubSection, Field } from "./ai-defaults-form-controls"; -/* eslint-disable @typescript-eslint/no-explicit-any */ + type AgentsData = Record; const DEFAULT: AgentsData = { defaults: {} }; diff --git a/ui/web/src/pages/config/sections/behavior-section.tsx b/ui/web/src/pages/config/sections/behavior-section.tsx index ea53322f..12c3ec88 100644 --- a/ui/web/src/pages/config/sections/behavior-section.tsx +++ b/ui/web/src/pages/config/sections/behavior-section.tsx @@ -8,7 +8,7 @@ import { BehaviorSessionsCard } from "./behavior-sessions-card"; import { BehaviorSecurityCard } from "./behavior-security-card"; import { BehaviorPendingCompactionCard, type PendingCompactionValues } from "./behavior-pending-compaction-card"; -/* eslint-disable @typescript-eslint/no-explicit-any */ + interface Props { config: Record; @@ -77,7 +77,7 @@ export function BehaviorSection({ config, onPatch, saving }: Props) { }); setPendingCompaction(ch.pending_compaction ?? {}); setDirty(false); - }, [config]); // eslint-disable-line react-hooks/exhaustive-deps + }, [config]); const markDirty = (setter: React.Dispatch>) => (v: T) => { setter(v); setDirty(true); }; diff --git a/ui/web/src/pages/config/sections/channels-section.tsx b/ui/web/src/pages/config/sections/channels-section.tsx index bf7aa8dc..99b8a5e8 100644 --- a/ui/web/src/pages/config/sections/channels-section.tsx +++ b/ui/web/src/pages/config/sections/channels-section.tsx @@ -10,7 +10,7 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@ import { Badge } from "@/components/ui/badge"; import { MultiUserPicker } from "@/components/shared/multi-user-picker"; -/* eslint-disable @typescript-eslint/no-explicit-any */ + type ChannelsData = Record; const CHANNEL_META: Record = { diff --git a/ui/web/src/pages/config/sections/shell-security-section.tsx b/ui/web/src/pages/config/sections/shell-security-section.tsx index 3fb43f6d..d1030484 100644 --- a/ui/web/src/pages/config/sections/shell-security-section.tsx +++ b/ui/web/src/pages/config/sections/shell-security-section.tsx @@ -14,7 +14,7 @@ import { import { useHttp } from "@/hooks/use-ws"; import { useAuthStore } from "@/stores/use-auth-store"; -/* eslint-disable @typescript-eslint/no-explicit-any */ + type ToolsData = Record; interface DenyGroupInfo { diff --git a/ui/web/src/pages/config/sections/tools-exec-section.tsx b/ui/web/src/pages/config/sections/tools-exec-section.tsx index 28d0619d..a0caf55a 100644 --- a/ui/web/src/pages/config/sections/tools-exec-section.tsx +++ b/ui/web/src/pages/config/sections/tools-exec-section.tsx @@ -19,7 +19,7 @@ import { } from "@/components/ui/select"; import { InfoLabel } from "@/components/shared/info-label"; -/* eslint-disable @typescript-eslint/no-explicit-any */ + type ToolsData = Record; interface Props { diff --git a/ui/web/src/pages/config/sections/tools-profile-section.tsx b/ui/web/src/pages/config/sections/tools-profile-section.tsx index 88f49981..2d1b850d 100644 --- a/ui/web/src/pages/config/sections/tools-profile-section.tsx +++ b/ui/web/src/pages/config/sections/tools-profile-section.tsx @@ -20,7 +20,7 @@ import { import { InfoLabel } from "@/components/shared/info-label"; import { ToolNameSelect } from "@/components/shared/tool-name-select"; -/* eslint-disable @typescript-eslint/no-explicit-any */ + type ToolsData = Record; interface Props { diff --git a/ui/web/src/pages/config/sections/tools-web-section.tsx b/ui/web/src/pages/config/sections/tools-web-section.tsx index d9375cf1..8f179a46 100644 --- a/ui/web/src/pages/config/sections/tools-web-section.tsx +++ b/ui/web/src/pages/config/sections/tools-web-section.tsx @@ -24,7 +24,7 @@ import { Separator } from "@/components/ui/separator"; import { InfoLabel } from "@/components/shared/info-label"; import { isSecret } from "@/lib/secret"; -/* eslint-disable @typescript-eslint/no-explicit-any */ + type ToolsData = Record; interface Props { diff --git a/ui/web/src/pages/config/sections/tts-section.tsx b/ui/web/src/pages/config/sections/tts-section.tsx index 089dae29..2fc589f6 100644 --- a/ui/web/src/pages/config/sections/tts-section.tsx +++ b/ui/web/src/pages/config/sections/tts-section.tsx @@ -5,7 +5,7 @@ import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { ROUTES } from "@/lib/constants"; -/* eslint-disable @typescript-eslint/no-explicit-any */ + interface Props { data: Record | undefined; } diff --git a/ui/web/src/pages/cron/cron-detail/cron-advanced-dialog.tsx b/ui/web/src/pages/cron/cron-detail/cron-advanced-dialog.tsx index b144aeb0..8ad03d6b 100644 --- a/ui/web/src/pages/cron/cron-detail/cron-advanced-dialog.tsx +++ b/ui/web/src/pages/cron/cron-detail/cron-advanced-dialog.tsx @@ -86,7 +86,7 @@ export function CronAdvancedDialog({ open, onOpenChange, job, onUpdate }: CronAd if (!open) return; reset(deriveDefaults(job)); fetchTargets(); - // eslint-disable-next-line react-hooks/exhaustive-deps + }, [open]); const handleSave = async () => { diff --git a/ui/web/src/pages/mcp/mcp-user-credentials-dialog.tsx b/ui/web/src/pages/mcp/mcp-user-credentials-dialog.tsx index 5855394e..c40a46ad 100644 --- a/ui/web/src/pages/mcp/mcp-user-credentials-dialog.tsx +++ b/ui/web/src/pages/mcp/mcp-user-credentials-dialog.tsx @@ -99,7 +99,7 @@ export function MCPUserCredentialsDialog({ .then(setStatus) .catch((err) => console.error("[MCPUserCredentials] load credentials failed:", err)) .finally(() => { setLoadingStatus(false); setInitialLoad(false); }); - }, [open, server.id, onGetCredentials, canManageUsers, selectedUserId]); // eslint-disable-line react-hooks/exhaustive-deps + }, [open, server.id, onGetCredentials, canManageUsers, selectedUserId]); const handleSave = async () => { setSaving(true); diff --git a/ui/web/src/pages/memory/episodic/episodic-tab.tsx b/ui/web/src/pages/memory/episodic/episodic-tab.tsx index 40e0b356..ff8b279d 100644 --- a/ui/web/src/pages/memory/episodic/episodic-tab.tsx +++ b/ui/web/src/pages/memory/episodic/episodic-tab.tsx @@ -38,7 +38,8 @@ export function EpisodicTab({ agentId }: Props) { const toggleExpand = (id: string) => { setExpanded((prev) => { const next = new Set(prev); - next.has(id) ? next.delete(id) : next.add(id); + if (next.has(id)) next.delete(id); + else next.add(id); return next; }); }; diff --git a/ui/web/src/pages/memory/knowledge-graph/kg-entity-detail-dialog.tsx b/ui/web/src/pages/memory/knowledge-graph/kg-entity-detail-dialog.tsx index 8bf85358..b3bf1abe 100644 --- a/ui/web/src/pages/memory/knowledge-graph/kg-entity-detail-dialog.tsx +++ b/ui/web/src/pages/memory/knowledge-graph/kg-entity-detail-dialog.tsx @@ -95,7 +95,7 @@ export function KGEntityDetailDialog({ open, onOpenChange, agentId, entity, getE if (open && entity && !traversing) { traverse(entity.id, entity.user_id, depth); } - }, [open, entity]); // eslint-disable-line react-hooks/exhaustive-deps + }, [open, entity]); // Build graph data from traversal results const graphData = useMemo(() => { diff --git a/ui/web/src/pages/providers/provider-detail/provider-advanced-dialog.tsx b/ui/web/src/pages/providers/provider-detail/provider-advanced-dialog.tsx index ade377bc..b629d827 100644 --- a/ui/web/src/pages/providers/provider-detail/provider-advanced-dialog.tsx +++ b/ui/web/src/pages/providers/provider-detail/provider-advanced-dialog.tsx @@ -75,7 +75,7 @@ export function ProviderAdvancedDialog({ setAcpIdleTTL(s.acpIdleTTL); setAcpPermMode(s.acpPermMode); setAcpWorkDir(s.acpWorkDir); - // eslint-disable-next-line react-hooks/exhaustive-deps + }, [open]); const [saving, setSaving] = useState(false); diff --git a/ui/web/src/pages/skills/hooks/use-skills.ts b/ui/web/src/pages/skills/hooks/use-skills.ts index 438abeac..a842c67e 100644 --- a/ui/web/src/pages/skills/hooks/use-skills.ts +++ b/ui/web/src/pages/skills/hooks/use-skills.ts @@ -51,7 +51,7 @@ export function useSkills() { // even if the SKILL_DEPS_* events were emitted before the client connected. useEffect(() => { if (connected) invalidate(); - }, [connected]); // eslint-disable-line react-hooks/exhaustive-deps + }, [connected]); const getSkill = useCallback( async (name: string) => { diff --git a/ui/web/src/pages/teams/board/board-container.tsx b/ui/web/src/pages/teams/board/board-container.tsx index 67a683a2..3f56586a 100644 --- a/ui/web/src/pages/teams/board/board-container.tsx +++ b/ui/web/src/pages/teams/board/board-container.tsx @@ -65,7 +65,7 @@ export const BoardContainer = memo(function BoardContainer({ // Re-fetch when filters change useEffect(() => { if (initialized) load(); - }, [statusFilter, selectedScope]); // eslint-disable-line react-hooks/exhaustive-deps + }, [statusFilter, selectedScope]); // ── Callbacks for children ── diff --git a/ui/web/src/pages/teams/task-sections/task-list.tsx b/ui/web/src/pages/teams/task-sections/task-list.tsx index c173b486..10452fee 100644 --- a/ui/web/src/pages/teams/task-sections/task-list.tsx +++ b/ui/web/src/pages/teams/task-sections/task-list.tsx @@ -97,6 +97,17 @@ export function TaskList({ } }, [deleteTasksBulk, teamId, selectedIds]); + const handleSingleDelete = useCallback(async () => { + if (!deleteTask || !deleteTargetId) return; + setSingleDeleting(true); + try { + await deleteTask(teamId, deleteTargetId); + setDeleteTargetId(null); + } finally { + setSingleDeleting(false); + } + }, [deleteTask, teamId, deleteTargetId]); + if (loading && tasks.length === 0) { return
{t("tasks.loading")}
; } @@ -117,17 +128,6 @@ export function TaskList({ setDeleteTargetId(taskId); }; - const handleSingleDelete = useCallback(async () => { - if (!deleteTask || !deleteTargetId) return; - setSingleDeleting(true); - try { - await deleteTask(teamId, deleteTargetId); - setDeleteTargetId(null); - } finally { - setSingleDeleting(false); - } - }, [deleteTask, teamId, deleteTargetId]); - const hasBulkDelete = !!deleteTasksBulk && pageTerminalIds.length > 0; const allPageSelected = pageTerminalIds.length > 0 && pageTerminalIds.every((id) => selectedIds.has(id)); const someSelected = selectedIds.size > 0 && !allPageSelected; diff --git a/ui/web/src/pages/teams/team-audit-logs-modal.tsx b/ui/web/src/pages/teams/team-audit-logs-modal.tsx index 8e2b9a8e..05afc0e2 100644 --- a/ui/web/src/pages/teams/team-audit-logs-modal.tsx +++ b/ui/web/src/pages/teams/team-audit-logs-modal.tsx @@ -103,7 +103,7 @@ export function TeamAuditLogsModal({ open, onOpenChange, teamId }: TeamAuditLogs setEvents([]); fetchEvents(0, false); } - }, [open]); // eslint-disable-line react-hooks/exhaustive-deps + }, [open]); const handleLoadMore = useCallback(() => { fetchEvents(events.length, true); diff --git a/ui/web/src/pages/usage/components/knowledge-chart.tsx b/ui/web/src/pages/usage/components/knowledge-chart.tsx index e4744ab3..a3414095 100644 --- a/ui/web/src/pages/usage/components/knowledge-chart.tsx +++ b/ui/web/src/pages/usage/components/knowledge-chart.tsx @@ -19,12 +19,6 @@ export function KnowledgeChart({ data, loading, granularity }: KnowledgeChartPro const { t } = useTranslation("usage"); const timezone = useUiStore((s) => s.timezone); - const hasData = data.some( - (d) => d.memory_docs > 0 || d.memory_chunks > 0 || d.kg_entities > 0 || d.kg_relations > 0, - ); - - if (!loading && !hasData) return null; - const chartData = useMemo(() => data.map((d) => ({ label: formatBucketTz(d.bucket_time, timezone, granularity), memory_docs: d.memory_docs, @@ -33,6 +27,12 @@ export function KnowledgeChart({ data, loading, granularity }: KnowledgeChartPro kg_relations: d.kg_relations, })), [data, granularity, timezone]); + const hasData = data.some( + (d) => d.memory_docs > 0 || d.memory_chunks > 0 || d.kg_entities > 0 || d.kg_relations > 0, + ); + + if (!loading && !hasData) return null; + return (