diff --git a/AGENTS.md b/AGENTS.md index 2e16c331..2226d647 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -37,4 +37,4 @@ ## Security & Configuration - Do not commit secrets. Use `.env.local` (see `env.local.example`). -- Node >= 18 (18/20/22 supported). Local dev and deploy can use Docker/Vercel; see `dev.md` and `docs/`. +- Node 22.x is required. Local dev and deploy can use Docker/Vercel; see `dev.md` and `docs/`. diff --git a/Dockerfile b/Dockerfile index 6dc17096..b23c17b7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:20-slim AS base +FROM node:22-slim AS base ENV PNPM_HOME="/pnpm" ENV PATH="$PNPM_HOME:$PATH" RUN npm install -g corepack@latest && corepack enable @@ -10,15 +10,15 @@ RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile RUN pnpm run build RUN pnpm mcp:build -FROM nginx:stable-alpine +FROM node:22-alpine # 安装htpasswd工具、dos2unix和supervisor -RUN apk add --no-cache apache2-utils dos2unix supervisor nodejs npm gettext curl +RUN apk add --no-cache nginx apache2-utils dos2unix supervisor gettext curl # 安装pnpm RUN npm install -g pnpm # 复制Nginx配置 -COPY docker/nginx.conf /etc/nginx/conf.d/default.conf +COPY docker/nginx.conf /etc/nginx/http.d/default.conf # 复制Web应用 COPY --from=build /app/packages/web/dist /usr/share/nginx/html @@ -59,4 +59,4 @@ RUN dos2unix /start-services.sh EXPOSE 80 # 使用自定义启动脚本 -CMD ["sh", "/start-services.sh"] \ No newline at end of file +CMD ["sh", "/start-services.sh"] diff --git a/dev.md b/dev.md index 8cb0d52c..df37e0f6 100644 --- a/dev.md +++ b/dev.md @@ -12,7 +12,7 @@ ## 本地开发环境配置 ### 基础环境要求 -- Node.js >= 18 +- Node.js 22.x - pnpm >= 8 - Git >= 2.0 - VSCode (推荐) diff --git a/docker/generate-auth.sh b/docker/generate-auth.sh index bfc58850..5ffc7dc1 100644 --- a/docker/generate-auth.sh +++ b/docker/generate-auth.sh @@ -6,7 +6,7 @@ if [ -n "$ACCESS_PASSWORD" ]; then if [ "$ACCESS_PASSWORD" = "" ]; then echo "警告: 设置了空密码,不安全。不启用Basic认证" # 创建空的auth配置(禁用认证) - cat > /etc/nginx/conf.d/auth.conf << EOF + cat > /etc/nginx/http.d/auth.conf << EOF # Basic认证未启用 - 密码为空 auth_basic off; EOF @@ -28,7 +28,7 @@ EOF chmod -R a+r /etc/nginx/auth # 创建启用认证的配置 - cat > /etc/nginx/conf.d/auth.conf << EOF + cat > /etc/nginx/http.d/auth.conf << EOF # 此文件由generate-auth.sh脚本自动生成 auth_basic "请输入访问凭据 (Please enter your credentials)"; auth_basic_user_file /etc/nginx/auth/.htpasswd; @@ -39,8 +39,8 @@ else echo "未设置ACCESS_PASSWORD环境变量,不启用Basic认证" # 创建空的auth配置(禁用认证) - cat > /etc/nginx/conf.d/auth.conf << EOF + cat > /etc/nginx/http.d/auth.conf << EOF # Basic认证未启用 auth_basic off; EOF -fi \ No newline at end of file +fi diff --git a/docker/nginx.conf b/docker/nginx.conf index bcef26f3..03a766ab 100644 --- a/docker/nginx.conf +++ b/docker/nginx.conf @@ -69,7 +69,7 @@ server { # SPA应用路由支持 location / { # 引入Basic认证配置 - include /etc/nginx/conf.d/auth.conf; + include /etc/nginx/http.d/auth.conf; try_files $uri $uri/ /index.html; expires -1; diff --git a/docker/start-services.sh b/docker/start-services.sh index a990078d..5018a324 100644 --- a/docker/start-services.sh +++ b/docker/start-services.sh @@ -5,8 +5,8 @@ mkdir -p /var/log/supervisor # 处理nginx配置文件中的环境变量 echo "Processing nginx configuration with environment variables..." -envsubst '${NGINX_PORT}' < /etc/nginx/conf.d/default.conf > /tmp/nginx.conf -mv /tmp/nginx.conf /etc/nginx/conf.d/default.conf +envsubst '${NGINX_PORT}' < /etc/nginx/http.d/default.conf > /tmp/nginx.conf +mv /tmp/nginx.conf /etc/nginx/http.d/default.conf echo "Nginx configuration updated with NGINX_PORT=${NGINX_PORT}" # 运行原有的nginx初始化脚本 diff --git a/docs/developer/technical-development-guide.md b/docs/developer/technical-development-guide.md index bf65cf6f..8a375ac4 100644 --- a/docs/developer/technical-development-guide.md +++ b/docs/developer/technical-development-guide.md @@ -815,7 +815,7 @@ const processedContent = computed(() => { ## 6. 开发环境要求 ### 6.1 开发环境 -- Node.js >= 18.0.0 +- Node.js 22.x - pnpm >= 8.15.0 - VS Code - Volar 1.8.x diff --git a/package.json b/package.json index a6ffa95b..8905181c 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "private": true, "packageManager": "pnpm@10.6.1", "engines": { - "node": "^18.0.0 || ^20.0.0 || ^22.0.0", + "node": "^22.0.0", "npm": "请使用pnpm代替npm", "yarn": "请使用pnpm代替yarn" }, @@ -59,39 +59,30 @@ "kill:dev": "node scripts/kill-dev.js" }, "devDependencies": { - "@intlify/unplugin-vue-i18n": "^11.0.1", - "@playwright/test": "^1.56.1", - "concurrently": "^8.2.2", - "cross-env": "^7.0.3", - "electron": "^39.2.6", - "i18next": "^24.2.2", - "i18next-browser-languagedetector": "^8.0.4", - "lodash-unified": "^1.0.3", + "@intlify/unplugin-vue-i18n": "^11.0.7", + "@playwright/test": "^1.58.2", + "concurrently": "^9.2.1", + "cross-env": "^10.1.0", "npm-run-all": "^4.1.5", - "rimraf": "^4.4.1", - "typescript": "^5.8.2" + "rimraf": "^6.1.3", + "typescript": "^6.0.2" }, "dependencies": { - "@element-plus/icons-vue": "^2.3.1", - "@floating-ui/core": "^1.6.9", - "@floating-ui/dom": "^1.6.13", - "@floating-ui/utils": "^0.2.9", + "@element-plus/icons-vue": "^2.3.2", + "@floating-ui/core": "^1.7.5", + "@floating-ui/dom": "^1.7.6", + "@floating-ui/utils": "^0.2.11", "@popperjs/core": "^2.11.8", - "@vue/reactivity": "^3.5.13", - "@vue/runtime-core": "^3.5.13", - "@vue/runtime-dom": "^3.5.13", - "@vue/shared": "^3.5.13", - "@vueuse/core": "^12.7.0", - "@vueuse/shared": "^12.7.0", + "@vue/reactivity": "^3.5.31", + "@vue/runtime-core": "^3.5.31", + "@vue/runtime-dom": "^3.5.31", + "@vue/shared": "^3.5.31", "async-validator": "^4.2.5", - "date-fns": "^3.6.0", - "date-fns-tz": "^3.1.3", - "dayjs": "^1.11.13", - "electron-to-chromium": "^1.5.177", - "lodash-es": "^4.17.21", + "dayjs": "^1.11.20", + "electron-to-chromium": "^1.5.327", "memoize-one": "^6.0.0", "normalize-wheel-es": "^1.2.0", - "vue-i18n": "^11.2.2" + "vue-i18n": "^11.3.0" }, "keywords": [], "author": "", @@ -99,9 +90,6 @@ "pnpm": { "onlyBuiltDependencies": [ "electron" - ], - "overrides": { - "builder-util-runtime": "9.2.10" - } + ] } } diff --git a/packages/core/package.json b/packages/core/package.json index ca93594c..8705c026 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -24,23 +24,23 @@ "test:integration": "vitest run tests/integration" }, "devDependencies": { - "@types/node": "^20.11.0", - "dotenv": "^16.4.7", - "msw": "^2.6.0", + "@types/node": "^22.19.15", + "dotenv": "^17.3.1", + "msw": "^2.12.14", "tsup": "^8.5.1", - "typescript": "^5.3.3", - "vitest": "^4.0.15" + "typescript": "^6.0.2", + "vitest": "^4.1.2" }, "dependencies": { - "@anthropic-ai/sdk": "^0.65.0", - "@google/genai": "^1.32.0", - "@types/mustache": "^4.2.5", - "dexie": "^4.0.11", - "diff": "^8.0.2", - "jsonrepair": "^3.13.1", + "@anthropic-ai/sdk": "^0.80.0", + "@google/genai": "^1.46.0", + "@types/mustache": "^4.2.6", + "dexie": "^4.4.1", + "diff": "^8.0.4", + "jsonrepair": "^3.13.3", "mustache": "^4.2.0", - "openai": "^4.83.0", - "uuid": "^11.0.5", - "zod": "^3.22.4" + "openai": "^6.33.0", + "uuid": "^11.1.0", + "zod": "^4.3.6" } } diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 6c83c787..5d0428ff 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -9,6 +9,7 @@ "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, + "ignoreDeprecations": "6.0", "noEmit": true, "strict": true, "noUnusedLocals": true, @@ -19,4 +20,4 @@ }, "include": ["src"], "exclude": ["node_modules", "dist", "tests"] -} \ No newline at end of file +} diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 17175215..e1141ec5 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -18,18 +18,17 @@ "logs:clean": "node -e \"const fs=require('fs');const path=require('path');const os=require('os');const logDir=path.join(os.homedir(),'AppData','Roaming','PromptOptimizer','logs');if(fs.existsSync(logDir)){fs.rmSync(logDir,{recursive:true});console.log('日志已清理');}else{console.log('日志目录不存在');}\"" }, "devDependencies": { - "cross-env": "^7.0.3", - "electron": "^39.2.6", - "electron-builder": "^26.0.12", - "electron-builder-squirrel-windows": "^26.0.12" + "cross-env": "^10.1.0", + "electron": "^41.1.0", + "electron-builder": "^26.8.1", + "electron-builder-squirrel-windows": "^26.8.1" }, "dependencies": { "@prompt-optimizer/core": "workspace:*", - "dotenv": "^16.0.0", - "electron-log": "^5.4.1", - "electron-updater": "6.6.2", - "node-fetch": "^2.7.0", - "undici": "^6.19.8" + "dotenv": "^17.3.1", + "electron-log": "^5.4.3", + "electron-updater": "6.8.3", + "undici": "^7.24.6" }, "build": { "appId": "com.promptoptimizer.desktop", diff --git a/packages/extension/package.json b/packages/extension/package.json index 11730d54..48b8a5af 100644 --- a/packages/extension/package.json +++ b/packages/extension/package.json @@ -12,26 +12,19 @@ }, "dependencies": { "@prompt-optimizer/ui": "workspace:*", - "element-plus": "^2.12.0", - "uuid": "^11.0.5", - "vue": "^3.5.13" + "uuid": "^11.1.0", + "vue": "^3.5.31" }, "devDependencies": { - "@tailwindcss/forms": "^0.5.10", - "@tailwindcss/typography": "^0.5.16", - "@tsconfig/node18": "^18.2.4", - "@types/node": "^22.13.4", - "@types/uuid": "^10.0.0", - "@vitejs/plugin-basic-ssl": "^2.1.0", - "@vitejs/plugin-vue": "^6.0.2", - "@vue/tsconfig": "^0.5.1", - "autoprefixer": "^10.4.20", - "dotenv": "^16.4.7", - "js-yaml": "^4.1.0", - "postcss": "^8.5.1", - "tailwindcss": "^3.4.17", - "typescript": "^5.0.0", - "vite": "^7.2.7", - "vitest": "^4.0.15" + "@tsconfig/node22": "^22.0.5", + "@types/node": "^22.19.15", + "@vitejs/plugin-basic-ssl": "^2.3.0", + "@vitejs/plugin-vue": "^6.0.5", + "@vue/tsconfig": "^0.9.1", + "dotenv": "^17.3.1", + "js-yaml": "^4.1.1", + "typescript": "^6.0.2", + "vite": "^8.0.3", + "vitest": "^4.1.2" } -} \ No newline at end of file +} diff --git a/packages/extension/postcss.config.js b/packages/extension/postcss.config.js deleted file mode 100644 index 387612ed..00000000 --- a/packages/extension/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -export default { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -} \ No newline at end of file diff --git a/packages/extension/src/style.css b/packages/extension/src/style.css index 9fbdea57..cd00d44b 100644 --- a/packages/extension/src/style.css +++ b/packages/extension/src/style.css @@ -1,7 +1,3 @@ -@tailwind base; -@tailwind components; -@tailwind utilities; - /* 基础样式设置 */ :root { font-size: 16px; /* 确保基础字体大小 */ @@ -19,4 +15,4 @@ body { text-rendering: optimizeLegibility; /* 优化文本渲染 */ -webkit-font-smoothing: antialiased; /* 字体平滑 */ -moz-osx-font-smoothing: grayscale; -} \ No newline at end of file +} diff --git a/packages/extension/tailwind.config.js b/packages/extension/tailwind.config.js deleted file mode 100644 index c2c418a1..00000000 --- a/packages/extension/tailwind.config.js +++ /dev/null @@ -1,26 +0,0 @@ -/** @type {import('tailwindcss').Config} */ -export default { - content: [ - "./index.html", - "./src/**/*.{vue,js,ts,jsx,tsx}", - "../../node_modules/@prompt-optimizer/ui/src/**/*.{vue,js,ts,jsx,tsx}", - "../ui/src/**/*.{vue,js,ts,jsx,tsx}" - ], - theme: { - extend: { - backgroundColor: { - 'input-bg': 'rgba(0, 0, 0, 0.2)', - }, - textColor: { - 'input-text': 'rgba(255, 255, 255, 0.9)', - }, - }, - }, - plugins: [ - require('@tailwindcss/forms')({ - strategy: 'class', - }), - require('@tailwindcss/typography'), - ], - important: true, -} \ No newline at end of file diff --git a/packages/extension/tsconfig.json b/packages/extension/tsconfig.json index 4a083726..24505eb3 100644 --- a/packages/extension/tsconfig.json +++ b/packages/extension/tsconfig.json @@ -4,7 +4,7 @@ "target": "ESNext", "useDefineForClassFields": true, "module": "ESNext", - "moduleResolution": "Node", + "moduleResolution": "bundler", "strict": true, "jsx": "preserve", "resolveJsonModule": true, @@ -13,7 +13,6 @@ "lib": ["ESNext", "DOM"], "skipLibCheck": true, "noEmit": true, - "baseUrl": ".", "paths": { "@/*": ["./src/*"], "@prompt-optimizer/ui": ["../ui/src/index.ts"], @@ -24,4 +23,4 @@ "references": [ { "path": "./tsconfig.node.json" } ] -} \ No newline at end of file +} diff --git a/packages/extension/tsconfig.node.json b/packages/extension/tsconfig.node.json index 13107e5f..e595dc69 100644 --- a/packages/extension/tsconfig.node.json +++ b/packages/extension/tsconfig.node.json @@ -1,10 +1,10 @@ { - "extends": "@tsconfig/node18/tsconfig.json", + "extends": "@tsconfig/node22/tsconfig.json", "include": ["./vite.config.*"], "compilerOptions": { "composite": true, "module": "ESNext", - "moduleResolution": "Node", + "moduleResolution": "bundler", "types": ["node"] } -} \ No newline at end of file +} diff --git a/packages/mcp-server/.eslintrc.json b/packages/mcp-server/.eslintrc.json deleted file mode 100644 index 32d22963..00000000 --- a/packages/mcp-server/.eslintrc.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "plugins": [ - "@typescript-eslint" - ], - "extends": [ - "eslint:recommended" - ], - "parserOptions": { - "ecmaVersion": 2022, - "sourceType": "module" - }, - "env": { - "node": true, - "es2022": true - }, - "rules": { - "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }], - "@typescript-eslint/no-explicit-any": "warn", - "prefer-const": "error", - "no-var": "error", - "no-console": "off", - "no-duplicate-imports": "error", - "no-undef": "off" - }, - "ignorePatterns": [ - "dist/", - "node_modules/", - "*.js", - "*.cjs", - "*.mjs" - ] -} diff --git a/packages/mcp-server/eslint.config.mjs b/packages/mcp-server/eslint.config.mjs new file mode 100644 index 00000000..0c487a19 --- /dev/null +++ b/packages/mcp-server/eslint.config.mjs @@ -0,0 +1,43 @@ +import js from '@eslint/js' +import globals from 'globals' +import tsPlugin from '@typescript-eslint/eslint-plugin' +import tsParser from '@typescript-eslint/parser' + +export default [ + { + ignores: [ + 'dist/**', + 'node_modules/**', + '*.js', + '*.cjs', + '*.mjs', + ], + }, + { + files: ['src/**/*.ts'], + languageOptions: { + parser: tsParser, + parserOptions: { + ecmaVersion: 2022, + sourceType: 'module', + }, + globals: { + ...globals.node, + }, + }, + plugins: { + '@typescript-eslint': tsPlugin, + }, + rules: { + ...js.configs.recommended.rules, + '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }], + '@typescript-eslint/no-explicit-any': 'warn', + 'prefer-const': 'error', + 'no-var': 'error', + 'no-console': 'off', + 'no-duplicate-imports': 'error', + 'no-unused-vars': 'off', + 'no-undef': 'off', + }, + }, +] diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json index 0eb82915..fd9e6048 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -26,25 +26,25 @@ "author": "Prompt Optimizer Team", "license": "AGPL-3.0-only", "dependencies": { - "@modelcontextprotocol/sdk": "^1.24.3", + "@modelcontextprotocol/sdk": "^1.28.0", "@prompt-optimizer/core": "workspace:*", - "debug": "^4.4.1", - "dotenv": "^16.4.7", - "express": "^4.21.2" + "debug": "^4.4.3", + "dotenv": "^17.3.1", + "express": "^5.2.1" }, "devDependencies": { - "@types/debug": "^4.1.12", - "@types/express": "^4.17.23", - "@types/node": "^20.11.0", - "@typescript-eslint/eslint-plugin": "^8.49.0", - "@typescript-eslint/parser": "^8.49.0", - "eslint": "^8.57.0", + "@types/debug": "^4.1.13", + "@types/express": "^5.0.6", + "@types/node": "^22.19.15", + "@typescript-eslint/eslint-plugin": "^8.57.2", + "@typescript-eslint/parser": "^8.57.2", + "eslint": "^10.1.0", "tsup": "^8.5.1", - "typescript": "^5.3.3", - "vitest": "^4.0.15" + "typescript": "^6.0.2", + "vitest": "^4.1.2" }, "engines": { - "node": ">=18.0.0" + "node": "^22.0.0" }, "files": [ "dist", diff --git a/packages/mcp-server/src/adapters/core-services.ts b/packages/mcp-server/src/adapters/core-services.ts index c80814cf..4267a3cd 100644 --- a/packages/mcp-server/src/adapters/core-services.ts +++ b/packages/mcp-server/src/adapters/core-services.ts @@ -197,7 +197,7 @@ export class CoreServicesManager { }); console.error(' Please check if your API keys are valid.'); } - } catch (error) { + } catch { // 如果检查环境变量失败,显示通用提示 console.error('💡 Please ensure you have set valid API keys.'); } diff --git a/packages/mcp-server/src/config/models.ts b/packages/mcp-server/src/config/models.ts index 2b0e62a0..89f7b03f 100644 --- a/packages/mcp-server/src/config/models.ts +++ b/packages/mcp-server/src/config/models.ts @@ -44,7 +44,7 @@ export async function setupDefaultModel( selectedModel = availableModels[0]; } - const [modelKey, modelConfig] = selectedModel; + const [, modelConfig] = selectedModel; // 3. 使用 core 的模型配置,确保模型启用 const finalConfig = { @@ -59,10 +59,9 @@ export async function setupDefaultModel( try { // 尝试更新现有模型 await modelManager.updateModel(mcpModelKey, finalConfig); - } catch (error) { + } catch { // 如果模型不存在,则添加新模型 await modelManager.addModel(mcpModelKey, finalConfig); } } - diff --git a/packages/mcp-server/tsconfig.json b/packages/mcp-server/tsconfig.json index bbe31366..ed6124cc 100644 --- a/packages/mcp-server/tsconfig.json +++ b/packages/mcp-server/tsconfig.json @@ -4,7 +4,7 @@ "rootDir": "./src", "module": "ESNext", "target": "ES2022", - "moduleResolution": "node", + "moduleResolution": "bundler", "allowSyntheticDefaultImports": true, "esModuleInterop": true, "strict": true, @@ -15,6 +15,7 @@ "sourceMap": true, "resolveJsonModule": true, "isolatedModules": true, + "ignoreDeprecations": "6.0", "noEmit": false, "lib": [ "ES2022", diff --git a/packages/ui/.eslintrc.json b/packages/ui/.eslintrc.json deleted file mode 100644 index 7d9fb71b..00000000 --- a/packages/ui/.eslintrc.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "root": true, - "parser": "vue-eslint-parser", - "parserOptions": { - "parser": "@typescript-eslint/parser", - "ecmaVersion": 2022, - "sourceType": "module", - "extraFileExtensions": [".vue"] - }, - "plugins": [ - "@typescript-eslint", - "vue" - ], - "extends": [ - "eslint:recommended" - ], - "env": { - "browser": true, - "es2022": true, - "node": true - }, - "rules": { - "@typescript-eslint/no-unused-vars": ["error", { - "argsIgnorePattern": "^_", - "destructuredArrayIgnorePattern": "^_", - "caughtErrorsIgnorePattern": "^_" - }], - "@typescript-eslint/no-explicit-any": "warn", - "prefer-const": "error", - "no-var": "error", - "no-console": "off", - "no-duplicate-imports": "error", - "no-undef": "off", - "no-empty": ["error", { "allowEmptyCatch": true }], - "no-unused-vars": "off", - "vue/multi-word-component-names": "off", - "vue/no-v-html": "off", - "vue/require-default-prop": "off", - "vue/no-unused-components": "warn", - "vue/no-unused-vars": "warn" - }, - "overrides": [ - { - "files": ["*.vue"], - "parser": "vue-eslint-parser", - "parserOptions": { - "parser": "@typescript-eslint/parser" - }, - "rules": { - "@typescript-eslint/no-unused-vars": ["error", { - "argsIgnorePattern": "^_", - "varsIgnorePattern": "^(props|emit|context|slots|attrs)$", - "destructuredArrayIgnorePattern": "^_", - "caughtErrorsIgnorePattern": "^_" - }], - "no-unused-vars": "off" - } - }, - { - "files": ["*.ts", "*.tsx"], - "parser": "@typescript-eslint/parser", - "rules": { - "@typescript-eslint/no-unused-vars": "off" - } - } - ], - "ignorePatterns": [ - "dist/", - "node_modules/", - "*.js", - "*.cjs", - "*.mjs" - ] -} diff --git a/packages/ui/eslint.config.mjs b/packages/ui/eslint.config.mjs new file mode 100644 index 00000000..17b7de43 --- /dev/null +++ b/packages/ui/eslint.config.mjs @@ -0,0 +1,110 @@ +import js from '@eslint/js' +import globals from 'globals' +import tsPlugin from '@typescript-eslint/eslint-plugin' +import tsParser from '@typescript-eslint/parser' +import vuePlugin from 'eslint-plugin-vue' +import vueParser from 'vue-eslint-parser' + +const sharedRules = { + ...js.configs.recommended.rules, + '@typescript-eslint/no-unused-vars': ['error', { + argsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }], + '@typescript-eslint/no-explicit-any': 'warn', + 'prefer-const': 'error', + 'no-var': 'error', + 'no-console': 'off', + 'no-duplicate-imports': 'error', + 'no-undef': 'off', + 'no-empty': ['error', { allowEmptyCatch: true }], + 'no-unused-vars': 'off', + 'vue/multi-word-component-names': 'off', + 'vue/no-v-html': 'off', + 'vue/require-default-prop': 'off', + 'vue/no-unused-components': 'warn', + 'vue/no-unused-vars': 'warn', +} + +export default [ + { + ignores: [ + 'dist/**', + 'node_modules/**', + '*.js', + '*.cjs', + '*.mjs', + ], + }, + { + files: ['src/**/*.{ts,tsx,vue}'], + languageOptions: { + parser: vueParser, + parserOptions: { + parser: tsParser, + ecmaVersion: 2022, + sourceType: 'module', + extraFileExtensions: ['.vue'], + }, + globals: { + ...globals.browser, + ...globals.node, + }, + }, + plugins: { + '@typescript-eslint': tsPlugin, + vue: vuePlugin, + }, + rules: sharedRules, + }, + { + files: ['src/**/*.vue'], + languageOptions: { + parser: vueParser, + parserOptions: { + parser: tsParser, + ecmaVersion: 2022, + sourceType: 'module', + extraFileExtensions: ['.vue'], + }, + globals: { + ...globals.browser, + ...globals.node, + }, + }, + plugins: { + '@typescript-eslint': tsPlugin, + vue: vuePlugin, + }, + rules: { + '@typescript-eslint/no-unused-vars': ['error', { + argsIgnorePattern: '^_', + varsIgnorePattern: '^(props|emit|context|slots|attrs)$', + destructuredArrayIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }], + 'no-unused-vars': 'off', + }, + }, + { + files: ['src/**/*.{ts,tsx}'], + languageOptions: { + parser: tsParser, + parserOptions: { + ecmaVersion: 2022, + sourceType: 'module', + }, + globals: { + ...globals.browser, + ...globals.node, + }, + }, + plugins: { + '@typescript-eslint': tsPlugin, + }, + rules: { + '@typescript-eslint/no-unused-vars': 'off', + }, + }, +] diff --git a/packages/ui/package.json b/packages/ui/package.json index 56905b54..38e56946 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -27,42 +27,46 @@ "build:win": "vite build", "test": "vitest run", "typecheck": "vue-tsc --noEmit", - "lint": "eslint src --ext .ts,.vue --no-eslintrc --config .eslintrc.json", - "lint:fix": "eslint src --ext .ts,.vue --no-eslintrc --config .eslintrc.json --fix" + "lint": "eslint src --ext .ts,.vue", + "lint:fix": "eslint src --ext .ts,.vue --fix" }, "dependencies": { - "@codemirror/autocomplete": "^6.19.0", - "@codemirror/language": "^6.11.3", - "@codemirror/state": "^6.5.2", - "@codemirror/tooltip": "^0.19.16", - "@codemirror/view": "^6.38.6", + "@codemirror/autocomplete": "^6.20.1", + "@codemirror/language": "^6.12.3", + "@codemirror/state": "^6.6.0", + "@codemirror/view": "^6.40.0", "@prompt-optimizer/core": "workspace:*", + "@vueuse/core": "^14.2.1", "@vicons/tabler": "^0.13.0", "codemirror": "^6.0.2", - "dompurify": "^3.2.4", + "dompurify": "^3.3.3", "highlight.js": "^11.11.1", - "markdown-it": "^14.1.0", - "naive-ui": "^2.42.0", - "pinia": "^3.0.3", - "uuid": "^11.0.5", - "vue": "^3.3.4", - "vue-router": "4" + "markdown-it": "^14.1.1", + "naive-ui": "^2.44.1", + "pinia": "^3.0.4", + "uuid": "^11.1.0", + "vue": "^3.5.31", + "vue-router": "^4.6.4" }, "devDependencies": { - "@types/node": "^22.13.10", - "@types/uuid": "^10.0.0", - "@typescript-eslint/eslint-plugin": "^8.49.0", - "@typescript-eslint/parser": "^8.49.0", - "@vitejs/plugin-vue": "^6.0.2", - "@vue/test-utils": "^2.4.5", - "@vue/tsconfig": "^0.5.1", - "eslint": "^8.57.0", - "vue-tsc": "^2.2.12", - "eslint-plugin-vue": "^10.4.0", - "jsdom": "^26.0.0", - "typescript": "^5.8.2", - "vite": "^7.2.7", - "vite-plugin-dts": "^4.5.3", - "vitest": "^4.0.15" + "@tailwindcss/forms": "^0.5.11", + "@tailwindcss/typography": "^0.5.19", + "@types/node": "^22.19.15", + "@typescript-eslint/eslint-plugin": "^8.57.2", + "@typescript-eslint/parser": "^8.57.2", + "@vitejs/plugin-vue": "^6.0.5", + "@vue/test-utils": "^2.4.6", + "@vue/tsconfig": "^0.9.1", + "autoprefixer": "^10.4.27", + "eslint": "^10.1.0", + "eslint-plugin-vue": "^10.8.0", + "jsdom": "^29.0.1", + "postcss": "^8.5.8", + "tailwindcss": "^3.4.19", + "typescript": "^6.0.2", + "vite": "^8.0.3", + "vite-plugin-dts": "^4.5.4", + "vitest": "^4.1.2", + "vue-tsc": "^3.2.6" } -} \ No newline at end of file +} diff --git a/packages/ui/src/components/HistoryDrawer.vue b/packages/ui/src/components/HistoryDrawer.vue index 41654e01..ae5adc5b 100644 --- a/packages/ui/src/components/HistoryDrawer.vue +++ b/packages/ui/src/components/HistoryDrawer.vue @@ -240,7 +240,7 @@ const emit = defineEmits<{ (e: 'deleteChain', chainId: string): void }>() -// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars +// eslint-disable-next-line @typescript-eslint/no-unused-vars const _toast = useToast() const expandedVersions = ref>({}) const searchQuery = ref('') @@ -274,7 +274,7 @@ const filteredHistory = computed(() => { }) // 切换版本展开/收起状态 -// eslint-disable-next-line @typescript-eslint/no-unused-vars, no-unused-vars +// eslint-disable-next-line @typescript-eslint/no-unused-vars const _toggleVersion = (recordId: string) => { expandedVersions.value = { ...expandedVersions.value, diff --git a/packages/ui/src/components/MainLayout.vue b/packages/ui/src/components/MainLayout.vue index 64c0feeb..2a1eec18 100644 --- a/packages/ui/src/components/MainLayout.vue +++ b/packages/ui/src/components/MainLayout.vue @@ -231,11 +231,11 @@ const openBrandWebsite = async () => { min-height: 32px; } -.core-navigation :deep(.function-mode-selector) { +.core-navigation .function-mode-selector { transform: scale(1.05); } -.core-navigation :deep(.n-radio-group) { +.core-navigation .n-radio-group { background: var(--modal-color, #fff); border-radius: 8px; padding: 4px; @@ -243,21 +243,21 @@ const openBrandWebsite = async () => { border: 1px solid var(--border-color, rgba(239, 239, 245, 0.6)); } -.core-navigation :deep(.n-radio-button) { +.core-navigation .n-radio-button { font-weight: 500; min-width: 60px; border-radius: 6px !important; transition: all 0.2s ease; } -.core-navigation :deep(.n-radio-button--checked) { +.core-navigation .n-radio-button--checked { background: var(--primary-color) !important; color: white !important; font-weight: 600; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12); } -.core-navigation :deep(.n-radio-button:not(.n-radio-button--checked):hover) { +.core-navigation .n-radio-button:not(.n-radio-button--checked):hover { background: var(--hover-color, rgba(0, 0, 0, 0.06)); } @@ -272,11 +272,11 @@ const openBrandWebsite = async () => { padding-left: 8px; } - .core-navigation :deep(.function-mode-selector) { + .core-navigation .function-mode-selector { transform: scale(0.95); } - .core-navigation :deep(.n-radio-button) { + .core-navigation .n-radio-button { min-width: 48px; font-size: 12px; } diff --git a/packages/ui/src/components/app-layout/PromptOptimizerApp.vue b/packages/ui/src/components/app-layout/PromptOptimizerApp.vue index e3c7a1b0..33f595ca 100644 --- a/packages/ui/src/components/app-layout/PromptOptimizerApp.vue +++ b/packages/ui/src/components/app-layout/PromptOptimizerApp.vue @@ -323,7 +323,7 @@ import { type IPromptService, type PromptRecordChain, type PatchOperation, type // 1. 基础 composables const hljsInstance = hljs; const i18n = useI18n(); -// eslint-disable-next-line @typescript-eslint/no-unused-vars + const t = i18n.t; // 在模板中使用 const toast = useToast(); @@ -404,11 +404,11 @@ const { services, isInitializing } = useAppInitializer(); // 🔧 修复:保存 composable 返回值,避免在 watch 回调中重复调用(导致 inject() 错误) // eslint-disable-next-line @typescript-eslint/no-unused-vars const functionModeApi = useFunctionMode(services); -// eslint-disable-next-line @typescript-eslint/no-unused-vars + const basicSubModeApi = useBasicSubMode(services); -// eslint-disable-next-line @typescript-eslint/no-unused-vars + const proSubModeApi = useProSubMode(services); -// eslint-disable-next-line @typescript-eslint/no-unused-vars + const imageSubModeApi = useImageSubMode(services); // 3.5. 🔧 Step A: 建立路由驱动的单一真源(优先于 state,避免双真源) diff --git a/packages/ui/src/components/evaluation/CompareHelpButton.vue b/packages/ui/src/components/evaluation/CompareHelpButton.vue index 7bf9a480..4423c915 100644 --- a/packages/ui/src/components/evaluation/CompareHelpButton.vue +++ b/packages/ui/src/components/evaluation/CompareHelpButton.vue @@ -65,8 +65,7 @@