diff --git a/.github/workflows/auto-i18n.yml b/.github/workflows/auto-i18n.yml index 6141c061f..2ca56c083 100644 --- a/.github/workflows/auto-i18n.yml +++ b/.github/workflows/auto-i18n.yml @@ -54,7 +54,7 @@ jobs: yarn install - name: 🏃‍♀️ Translate - run: yarn sync:i18n && yarn auto:i18n + run: yarn i18n:sync && yarn i18n:translate - name: 🔍 Format run: yarn format diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml index 125844900..1f7bf7d78 100644 --- a/.github/workflows/pr-ci.yml +++ b/.github/workflows/pr-ci.yml @@ -58,7 +58,7 @@ jobs: run: yarn typecheck - name: i18n Check - run: yarn check:i18n + run: yarn i18n:check - name: Test run: yarn test diff --git a/CLAUDE.md b/CLAUDE.md index c96fc0e40..c68187db9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -28,7 +28,7 @@ When creating a Pull Request, you MUST: - **Development**: `yarn dev` - Runs Electron app in development mode with hot reload - **Debug**: `yarn debug` - Starts with debugging enabled, use `chrome://inspect` to attach debugger - **Build Check**: `yarn build:check` - **REQUIRED** before commits (lint + test + typecheck) - - If having i18n sort issues, run `yarn sync:i18n` first to sync template + - If having i18n sort issues, run `yarn i18n:sync` first to sync template - If having formatting issues, run `yarn format` first - **Test**: `yarn test` - Run all tests (Vitest) across main and renderer processes - **Single Test**: @@ -40,20 +40,23 @@ When creating a Pull Request, you MUST: ## Project Architecture ### Electron Structure + - **Main Process** (`src/main/`): Node.js backend with services (MCP, Knowledge, Storage, etc.) - **Renderer Process** (`src/renderer/`): React UI with Redux state management - **Preload Scripts** (`src/preload/`): Secure IPC bridge ### Key Components + - **AI Core** (`src/renderer/src/aiCore/`): Middleware pipeline for multiple AI providers. - **Services** (`src/main/services/`): MCPService, KnowledgeService, WindowService, etc. - **Build System**: Electron-Vite with experimental rolldown-vite, yarn workspaces. - **State Management**: Redux Toolkit (`src/renderer/src/store/`) for predictable state. ### Logging + ```typescript -import { loggerService } from '@logger' -const logger = loggerService.withContext('moduleName') +import { loggerService } from "@logger"; +const logger = loggerService.withContext("moduleName"); // Renderer: loggerService.initWindowSource('windowName') first -logger.info('message', CONTEXT) +logger.info("message", CONTEXT); ``` diff --git a/docs/en/guides/i18n.md b/docs/en/guides/i18n.md index a3284e3ab..7fccfde69 100644 --- a/docs/en/guides/i18n.md +++ b/docs/en/guides/i18n.md @@ -71,7 +71,7 @@ Tools like i18n Ally cannot parse dynamic content within template strings, resul ```javascript // Not recommended - Plugin cannot resolve -const message = t(`fruits.${fruit}`) +const message = t(`fruits.${fruit}`); ``` #### 2. **No Real-time Rendering in Editor** @@ -91,14 +91,14 @@ For example: ```ts // src/renderer/src/i18n/label.ts const themeModeKeyMap = { - dark: 'settings.theme.dark', - light: 'settings.theme.light', - system: 'settings.theme.system' -} as const + dark: "settings.theme.dark", + light: "settings.theme.light", + system: "settings.theme.system", +} as const; export const getThemeModeLabel = (key: string): string => { - return themeModeKeyMap[key] ? t(themeModeKeyMap[key]) : key -} + return themeModeKeyMap[key] ? t(themeModeKeyMap[key]) : key; +}; ``` By avoiding template strings, you gain better developer experience, more reliable translation checks, and a more maintainable codebase. @@ -107,7 +107,7 @@ By avoiding template strings, you gain better developer experience, more reliabl The project includes several scripts to automate i18n-related tasks: -### `check:i18n` - Validate i18n Structure +### `i18n:check` - Validate i18n Structure This script checks: @@ -116,10 +116,10 @@ This script checks: - Whether keys are properly sorted ```bash -yarn check:i18n +yarn i18n:check ``` -### `sync:i18n` - Synchronize JSON Structure and Sort Order +### `i18n:sync` - Synchronize JSON Structure and Sort Order This script uses `zh-cn.json` as the source of truth to sync structure across all language files, including: @@ -128,14 +128,14 @@ This script uses `zh-cn.json` as the source of truth to sync structure across al 3. Sorting keys automatically ```bash -yarn sync:i18n +yarn i18n:sync ``` -### `auto:i18n` - Automatically Translate Pending Texts +### `i18n:translate` - Automatically Translate Pending Texts This script fills in texts marked as `[to be translated]` using machine translation. -Typically, after adding new texts in `zh-cn.json`, run `sync:i18n`, then `auto:i18n` to complete translations. +Typically, after adding new texts in `zh-cn.json`, run `i18n:sync`, then `i18n:translate` to complete translations. Before using this script, set the required environment variables: @@ -148,30 +148,20 @@ MODEL="qwen-plus-latest" Alternatively, add these variables directly to your `.env` file. ```bash -yarn auto:i18n -``` - -### `update:i18n` - Object-level Translation Update - -Updates translations in language files under `src/renderer/src/i18n/translate` at the object level, preserving existing translations and only updating new content. - -**Not recommended** — prefer `auto:i18n` for translation tasks. - -```bash -yarn update:i18n +yarn i18n:translate ``` ### Workflow 1. During development, first add the required text in `zh-cn.json` 2. Confirm it displays correctly in the Chinese environment -3. Run `yarn sync:i18n` to propagate the keys to other language files -4. Run `yarn auto:i18n` to perform machine translation +3. Run `yarn i18n:sync` to propagate the keys to other language files +4. Run `yarn i18n:translate` to perform machine translation 5. Grab a coffee and let the magic happen! ## Best Practices 1. **Use Chinese as Source Language**: All development starts in Chinese, then translates to other languages. -2. **Run Check Script Before Commit**: Use `yarn check:i18n` to catch i18n issues early. +2. **Run Check Script Before Commit**: Use `yarn i18n:check` to catch i18n issues early. 3. **Translate in Small Increments**: Avoid accumulating a large backlog of untranslated content. 4. **Keep Keys Semantically Clear**: Keys should clearly express their purpose, e.g., `user.profile.avatar.upload.error` diff --git a/docs/zh/guides/i18n.md b/docs/zh/guides/i18n.md index 82624d35c..c8a8ccc66 100644 --- a/docs/zh/guides/i18n.md +++ b/docs/zh/guides/i18n.md @@ -1,17 +1,17 @@ # 如何优雅地做好 i18n -## 使用i18n ally插件提升开发体验 +## 使用 i18n ally 插件提升开发体验 -i18n ally是一个强大的VSCode插件,它能在开发阶段提供实时反馈,帮助开发者更早发现文案缺失和错译问题。 +i18n ally 是一个强大的 VSCode 插件,它能在开发阶段提供实时反馈,帮助开发者更早发现文案缺失和错译问题。 项目中已经配置好了插件设置,直接安装即可。 ### 开发时优势 - **实时预览**:翻译文案会直接显示在编辑器中 -- **错误检测**:自动追踪标记出缺失的翻译或未使用的key -- **快速跳转**:可通过key直接跳转到定义处(Ctrl/Cmd + click) -- **自动补全**:输入i18n key时提供自动补全建议 +- **错误检测**:自动追踪标记出缺失的翻译或未使用的 key +- **快速跳转**:可通过 key 直接跳转到定义处(Ctrl/Cmd + click) +- **自动补全**:输入 i18n key 时提供自动补全建议 ### 效果展示 @@ -23,9 +23,9 @@ i18n ally是一个强大的VSCode插件,它能在开发阶段提供实时反 ## i18n 约定 -### **绝对避免使用flat格式** +### **绝对避免使用 flat 格式** -绝对避免使用flat格式,如`"add.button.tip": "添加"`。应采用清晰的嵌套结构: +绝对避免使用 flat 格式,如`"add.button.tip": "添加"`。应采用清晰的嵌套结构: ```json // 错误示例 - flat结构 @@ -52,14 +52,14 @@ i18n ally是一个强大的VSCode插件,它能在开发阶段提供实时反 #### 为什么要使用嵌套结构 1. **自然分组**:通过对象结构天然能将相关上下文的文案分到一个组别中 -2. **插件要求**:i18n ally 插件需要嵌套或flat格式其一的文件才能正常分析 +2. **插件要求**:i18n ally 插件需要嵌套或 flat 格式其一的文件才能正常分析 ### **避免在`t()`中使用模板字符串** -**强烈建议避免使用模板字符串**进行动态插值。虽然模板字符串在JavaScript开发中非常方便,但在国际化场景下会带来一系列问题。 +**强烈建议避免使用模板字符串**进行动态插值。虽然模板字符串在 JavaScript 开发中非常方便,但在国际化场景下会带来一系列问题。 1. **插件无法跟踪** - i18n ally等工具无法解析模板字符串中的动态内容,导致: + i18n ally 等工具无法解析模板字符串中的动态内容,导致: - 无法正确显示实时预览 - 无法检测翻译缺失 @@ -67,11 +67,11 @@ i18n ally是一个强大的VSCode插件,它能在开发阶段提供实时反 ```javascript // 不推荐 - 插件无法解析 - const message = t(`fruits.${fruit}`) + const message = t(`fruits.${fruit}`); ``` 2. **编辑器无法实时渲染** - 在IDE中,模板字符串会显示为原始代码而非最终翻译结果,降低了开发体验。 + 在 IDE 中,模板字符串会显示为原始代码而非最终翻译结果,降低了开发体验。 3. **更难以维护** 由于插件无法跟踪这样的文案,编辑器中也无法渲染,开发者必须人工确认语言文件中是否存在相应的文案。 @@ -85,36 +85,36 @@ i18n ally是一个强大的VSCode插件,它能在开发阶段提供实时反 ```ts // src/renderer/src/i18n/label.ts const themeModeKeyMap = { - dark: 'settings.theme.dark', - light: 'settings.theme.light', - system: 'settings.theme.system' -} as const + dark: "settings.theme.dark", + light: "settings.theme.light", + system: "settings.theme.system", +} as const; export const getThemeModeLabel = (key: string): string => { - return themeModeKeyMap[key] ? t(themeModeKeyMap[key]) : key -} + return themeModeKeyMap[key] ? t(themeModeKeyMap[key]) : key; +}; ``` 通过避免模板字符串,可以获得更好的开发体验、更可靠的翻译检查以及更易维护的代码库。 ## 自动化脚本 -项目中有一系列脚本来自动化i18n相关任务: +项目中有一系列脚本来自动化 i18n 相关任务: -### `check:i18n` - 检查i18n结构 +### `i18n:check` - 检查 i18n 结构 此脚本会检查: - 所有语言文件是否为嵌套结构 -- 是否存在缺失的key -- 是否存在多余的key +- 是否存在缺失的 key +- 是否存在多余的 key - 是否已经有序 ```bash -yarn check:i18n +yarn i18n:check ``` -### `sync:i18n` - 同步json结构与排序 +### `i18n:sync` - 同步 json 结构与排序 此脚本以`zh-cn.json`文件为基准,将结构同步到其他语言文件,包括: @@ -123,14 +123,14 @@ yarn check:i18n 3. 自动排序 ```bash -yarn sync:i18n +yarn i18n:sync ``` -### `auto:i18n` - 自动翻译待翻译文本 +### `i18n:translate` - 自动翻译待翻译文本 次脚本自动将标记为待翻译的文本通过机器翻译填充。 -通常,在`zh-cn.json`中添加所需文案后,执行`sync:i18n`即可自动完成翻译。 +通常,在`zh-cn.json`中添加所需文案后,执行`i18n:sync`即可自动完成翻译。 使用该脚本前,需要配置环境变量,例如: @@ -143,29 +143,19 @@ MODEL="qwen-plus-latest" 你也可以通过直接编辑`.env`文件来添加环境变量。 ```bash -yarn auto:i18n -``` - -### `update:i18n` - 对象级别翻译更新 - -对`src/renderer/src/i18n/translate`中的语言文件进行对象级别的翻译更新,保留已有翻译,只更新新增内容。 - -**不建议**使用该脚本,更推荐使用`auto:i18n`进行翻译。 - -```bash -yarn update:i18n +yarn i18n:translate ``` ### 工作流 1. 开发阶段,先在`zh-cn.json`中添加所需文案 -2. 确认在中文环境下显示无误后,使用`yarn sync:i18n`将文案同步到其他语言文件 -3. 使用`yarn auto:i18n`进行自动翻译 +2. 确认在中文环境下显示无误后,使用`yarn i18n:sync`将文案同步到其他语言文件 +3. 使用`yarn i18n:translate`进行自动翻译 4. 喝杯咖啡,等翻译完成吧! ## 最佳实践 1. **以中文为源语言**:所有开发首先使用中文,再翻译为其他语言 -2. **提交前运行检查脚本**:使用`yarn check:i18n`检查i18n是否有问题 +2. **提交前运行检查脚本**:使用`yarn i18n:check`检查 i18n 是否有问题 3. **小步提交翻译**:避免积累大量未翻译文本 -4. **保持key语义明确**:key应能清晰表达其用途,如`user.profile.avatar.upload.error` +4. **保持 key 语义明确**:key 应能清晰表达其用途,如`user.profile.avatar.upload.error` diff --git a/package.json b/package.json index fa63de9de..3fd6d1741 100644 --- a/package.json +++ b/package.json @@ -53,10 +53,10 @@ "typecheck": "concurrently -n \"node,web\" -c \"cyan,magenta\" \"npm run typecheck:node\" \"npm run typecheck:web\"", "typecheck:node": "tsgo --noEmit -p tsconfig.node.json --composite false", "typecheck:web": "tsgo --noEmit -p tsconfig.web.json --composite false", - "check:i18n": "dotenv -e .env -- tsx scripts/check-i18n.ts", - "sync:i18n": "dotenv -e .env -- tsx scripts/sync-i18n.ts", - "update:i18n": "dotenv -e .env -- tsx scripts/update-i18n.ts", - "auto:i18n": "dotenv -e .env -- tsx scripts/auto-translate-i18n.ts", + "i18n:check": "dotenv -e .env -- tsx scripts/check-i18n.ts", + "i18n:sync": "dotenv -e .env -- tsx scripts/sync-i18n.ts", + "i18n:translate": "dotenv -e .env -- tsx scripts/auto-translate-i18n.ts", + "i18n:all": "yarn i18n:check && yarn i18n:sync && yarn i18n:translate", "update:languages": "tsx scripts/update-languages.ts", "update:upgrade-config": "tsx scripts/update-app-upgrade-config.ts", "test": "vitest run --silent", @@ -70,7 +70,7 @@ "test:e2e": "yarn playwright test", "test:lint": "oxlint --deny-warnings && eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --cache", "test:scripts": "vitest scripts", - "lint": "oxlint --fix && eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --cache && yarn typecheck && yarn check:i18n && yarn format:check", + "lint": "oxlint --fix && eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --cache && yarn typecheck && yarn i18n:check && yarn format:check", "format": "biome format --write && biome lint --write", "format:check": "biome format && biome lint", "prepare": "git config blame.ignoreRevsFile .git-blame-ignore-revs && husky", diff --git a/scripts/auto-translate-i18n.ts b/scripts/auto-translate-i18n.ts index 7a1bea6f3..f57913b01 100644 --- a/scripts/auto-translate-i18n.ts +++ b/scripts/auto-translate-i18n.ts @@ -50,7 +50,7 @@ Usage Instructions: - pt-pt (Portuguese) Run Command: -yarn auto:i18n +yarn i18n:translate Performance Optimization Recommendations: - For stable API services: MAX_CONCURRENT_TRANSLATIONS=8, TRANSLATION_DELAY_MS=50 diff --git a/scripts/check-i18n.ts b/scripts/check-i18n.ts index 573547410..ac1adc3de 100644 --- a/scripts/check-i18n.ts +++ b/scripts/check-i18n.ts @@ -145,7 +145,7 @@ export function main() { console.log('i18n 检查已通过') } catch (e) { console.error(e) - throw new Error(`检查未通过。尝试运行 yarn sync:i18n 以解决问题。`) + throw new Error(`检查未通过。尝试运行 yarn i18n:sync 以解决问题。`) } }