@agentscope-ai/i18n 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -135
- package/i18n.config.example.js +106 -0
- package/lib/cli.js +112 -221
- package/lib/core/ast-processor.js +17 -21
- package/lib/core/checker.js +544 -0
- package/lib/core/file-processor.js +44 -204
- package/lib/core/translator.js +95 -936
- package/lib/index.js +2 -8
- package/lib/parse-jsx.js +33 -23
- package/lib/utils/ast-utils.js +48 -25
- package/lib/utils/file-utils.js +50 -11
- package/package.json +10 -5
- package/skills/i18n-helper/SKILL.md +186 -82
|
@@ -1,19 +1,42 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: i18n-helper
|
|
3
|
-
description: 国际化(i18n)自动化助手。当用户要对项目目录执行i18n增量翻译(如「翻译 @src/xxx」「i18n」「国际化」「patch
|
|
3
|
+
description: 国际化(i18n)自动化助手。当用户要对项目目录执行i18n增量翻译(如「翻译 @src/xxx」「i18n」「国际化」「patch」「提翻 @src/xxx」「@src/xxx 翻译」「@src/xxx 提翻」),或要修改指定i18n key的中英文文案(如「修改xxx的英文」「英文改为」),或要检查翻译状态(如「检查翻译」「翻译检查」「国际化检查」「i18n check」)时触发。仅翻译普通文案时不触发。
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# 国际化自动化助手
|
|
7
7
|
|
|
8
8
|
## 项目配置
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
10
|
+
工具:`@ali/agentscope-ai-i18n`,配置文件:项目根目录的 `i18n.config.js`。
|
|
11
|
+
|
|
12
|
+
执行任何操作前,先读取 `i18n.config.js` 获取以下信息:
|
|
13
|
+
- `medusa.appName` — 美杜莎应用名
|
|
14
|
+
- `medusa.appId` — 美杜莎应用ID
|
|
15
|
+
- `medusa.tag` — 标签
|
|
16
|
+
- `localesFilePath` — 翻译文件目录
|
|
17
|
+
- `dashScope.valueTranslateAppId` — 从其 key 推断支持的语言列表
|
|
18
|
+
|
|
19
|
+
## 前置环境检查
|
|
20
|
+
|
|
21
|
+
**每次执行任何 i18n 操作前,必须先检查以下配置文件是否存在:**
|
|
22
|
+
|
|
23
|
+
1. **检查 `i18n.config.js`**:如果项目根目录下不存在 `i18n.config.js`(或 `i18n.config.cjs`),停止操作并提示用户:
|
|
24
|
+
- 运行 `npx i18n init-config` 生成配置文件
|
|
25
|
+
- 根据项目实际情况修改 `targetPath`、`keyPrefix`、`medusa` 等配置
|
|
26
|
+
|
|
27
|
+
2. **检查 `.env`**:如果项目根目录下不存在 `.env` 文件或缺少必要的环境变量(`DASHSCOPE_APIKEY`、`BUC_ID`),停止操作并提示用户:
|
|
28
|
+
- 在 `.env` 中填写 `DASHSCOPE_APIKEY`(AI 翻译所需)
|
|
29
|
+
- 在 `.env` 中填写 `BUC_ID`(同步美杜莎所需,可在 https://wanx-medusa-config.pre-fn.alibaba-inc.com/ 登录后右上角查看)
|
|
30
|
+
|
|
31
|
+
## Medusa 权限问题诊断
|
|
32
|
+
|
|
33
|
+
当调用 medusa 相关接口(如 `npx i18n medusa`、sync-to-mds 脚本等)返回的不是 JSON 而是 HTML 页面时,通常是因为没有该美杜莎应用的 ACL 权限。此时需要停止操作并提示用户前往以下两个平台申请权限:
|
|
34
|
+
|
|
35
|
+
1. **Medusa 平台**:`https://mds-portal.alibaba-inc.com/applications/detail?navItemType=keyList&appId={medusa.appId}&appName={medusa.appName}`
|
|
36
|
+
(将 `{medusa.appId}` 和 `{medusa.appName}` 替换为 `i18n.config.js` 中的实际值)
|
|
37
|
+
2. **MCMS 平台**:`https://mcms-portal.alibaba-inc.com`
|
|
38
|
+
|
|
39
|
+
提示用户在以上两个平台完成 ACL 权限申请后重试。
|
|
17
40
|
|
|
18
41
|
## 场景判断
|
|
19
42
|
|
|
@@ -25,16 +48,31 @@ description: 国际化(i18n)自动化助手。当用户要对项目目录执行i
|
|
|
25
48
|
- 仅出现「翻译」或「翻译 xxx」但不带目录路径时,**不触发**此场景
|
|
26
49
|
|
|
27
50
|
**修改文案** — 用户要修改指定 i18n key 的中英文文案:
|
|
28
|
-
- 触发条件:用户消息中包含 i18n key(如 `
|
|
51
|
+
- 触发条件:用户消息中包含 i18n key(如 `app.xxx.xxx`)或引用了含有 `$i18n.get` 的代码行
|
|
29
52
|
- 关键词:「修改 xxx 的中文/英文」「把 xxx 改成」「英文改为」「中文改为」「英文改成」「中文改成」「更新文案」
|
|
30
53
|
|
|
54
|
+
**检查翻译** — 用户要检查项目翻译状态,确认是否有未翻译文案、缺失 key 等:
|
|
55
|
+
- 触发条件:用户消息中包含检查/巡查翻译状态的意图
|
|
56
|
+
- 关键词:「检查翻译」「国际化检查」「i18n check」「翻译检查」「检查i18n」「翻译状态」「check」
|
|
57
|
+
|
|
58
|
+
## 核心原则:翻译必须通过美杜莎平台
|
|
59
|
+
|
|
60
|
+
**禁止直接修改本地 `locales/` 目录下的翻译 JSON 文件来新增或修改翻译。** 所有翻译变更必须经过以下流程:
|
|
61
|
+
|
|
62
|
+
1. 使用 `npx i18n patch`(或 `translate`)生成 Excel 文件
|
|
63
|
+
2. 将 Excel 上传到美杜莎平台
|
|
64
|
+
3. 在美杜莎平台上确认并发布
|
|
65
|
+
4. 通过 `npx i18n medusa` 从平台拉取最新翻译到本地
|
|
66
|
+
|
|
67
|
+
本地 locale 文件仅作为平台翻译的本地缓存,不应手动编辑。
|
|
68
|
+
|
|
31
69
|
## 增量翻译:扫描中文 + 生成 Excel + 上传美杜莎
|
|
32
70
|
|
|
33
|
-
|
|
71
|
+
这是一个分步工作流,在每步完成后暂停让用户确认,再继续下一步。
|
|
34
72
|
|
|
35
|
-
1
|
|
73
|
+
### Step 1: patch — 扫描中文 + AI 翻译 + 生成 Excel
|
|
36
74
|
|
|
37
|
-
|
|
75
|
+
1. **提交当前代码(创建回退点)**
|
|
38
76
|
|
|
39
77
|
```bash
|
|
40
78
|
git add -A && git commit -m "chore: save before i18n patch"
|
|
@@ -43,120 +81,186 @@ description: 国际化(i18n)自动化助手。当用户要对项目目录执行i
|
|
|
43
81
|
2. **执行增量翻译命令**
|
|
44
82
|
|
|
45
83
|
如果用户指定了目标目录 `<dir>`:
|
|
46
|
-
|
|
47
84
|
```bash
|
|
48
85
|
npx i18n patch --target-path <dir> --skip-confirm
|
|
49
86
|
```
|
|
50
87
|
|
|
51
88
|
否则使用默认配置:
|
|
52
|
-
|
|
53
89
|
```bash
|
|
54
90
|
npx i18n patch --skip-confirm
|
|
55
91
|
```
|
|
56
92
|
|
|
57
93
|
`--skip-confirm` 会跳过所有确认提示,自动完成翻译流程。等待命令完成。
|
|
58
94
|
|
|
95
|
+
**可选引擎**:默认使用 MT 机器翻译,如需使用 Agent 批量翻译,追加 `--engine agent`。
|
|
96
|
+
|
|
59
97
|
3. **定位并打开生成的 Excel 文件**
|
|
60
98
|
|
|
61
|
-
命令执行完成后,在 `
|
|
99
|
+
命令执行完成后,在 `localesFilePath` 目录下查找最新生成的 `medusa-translations-*.xlsx` 文件,使用 `open` 命令打开它,方便用户预览确认翻译内容:
|
|
62
100
|
|
|
63
101
|
```bash
|
|
64
|
-
open "
|
|
102
|
+
open "<localesFilePath>/medusa-translations-<timestamp>.xlsx"
|
|
65
103
|
```
|
|
66
104
|
|
|
67
|
-
4.
|
|
105
|
+
4. **暂停确认**
|
|
106
|
+
|
|
107
|
+
使用 AskQuestion 询问用户:
|
|
108
|
+
- Excel 文件已打开,请确认翻译内容
|
|
109
|
+
- 选项:「继续上传到美杜莎」/「暂停,我先手动检查 Excel」
|
|
110
|
+
|
|
111
|
+
### Step 2: 上传到美杜莎平台
|
|
112
|
+
|
|
113
|
+
1. **打开美杜莎上传页面**
|
|
68
114
|
|
|
69
115
|
使用 `open` 命令在系统默认浏览器(Chrome)中打开以下地址,不要使用 Cursor 内置浏览器:
|
|
70
116
|
|
|
71
117
|
```bash
|
|
72
|
-
open "https://mds-portal.alibaba-inc.com/applications/upload?appName={
|
|
118
|
+
open "https://mds-portal.alibaba-inc.com/applications/upload?appName={medusa.appName}&appId={medusa.appId}&&appGroupId=&lastPage=%5Bobject%20Object%5D"
|
|
73
119
|
```
|
|
74
120
|
|
|
75
|
-
|
|
121
|
+
> 将 `{medusa.appName}` 和 `{medusa.appId}` 替换为 `i18n.config.js` 中的实际值。
|
|
122
|
+
|
|
123
|
+
2. **提示用户操作**
|
|
76
124
|
|
|
77
125
|
告知用户:
|
|
78
|
-
- Excel 文件已打开,请确认翻译内容
|
|
79
126
|
- **如果有文案是产品指定,请添加 do_not_trans 标签!**
|
|
80
127
|
- 在美杜莎页面上传该 Excel 文件,上传后确认导入
|
|
81
|
-
- 然后筛选未发布文案(标签={
|
|
128
|
+
- 然后筛选未发布文案(标签={medusa.tag},发布状态=未发布),全选后发布中文
|
|
82
129
|
- 下一个工作日翻译同学会收到翻译任务(T+1)
|
|
130
|
+
- 如果上传/导入时页面报错或跳转到登录页,可能是权限问题,参考上方「Medusa 权限问题诊断」
|
|
83
131
|
|
|
84
|
-
|
|
132
|
+
3. **暂停确认**
|
|
133
|
+
|
|
134
|
+
使用 AskQuestion 询问用户:
|
|
135
|
+
- 选项:「已上传并发布,继续替换代码」/「暂停,我先去美杜莎确认」
|
|
85
136
|
|
|
86
|
-
###
|
|
137
|
+
### Step 3: replace — 替换代码中的中文
|
|
87
138
|
|
|
88
|
-
|
|
139
|
+
1. **执行替换命令**
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
npx i18n replace
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
或指定文件:
|
|
146
|
+
```bash
|
|
147
|
+
npx i18n replace --file <file>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
2. **完成**
|
|
151
|
+
|
|
152
|
+
告知用户:
|
|
153
|
+
- 代码替换完成
|
|
154
|
+
- 请检查 git diff 确认改动
|
|
155
|
+
- 如不满意可 `git revert HEAD` 回退
|
|
156
|
+
|
|
157
|
+
## 检查翻译:拉取最新文案 + 检查缺失 + 引导后续操作
|
|
158
|
+
|
|
159
|
+
### 步骤
|
|
160
|
+
1. **拉取美杜莎最新翻译到本地**
|
|
161
|
+
```bash
|
|
162
|
+
npx i18n medusa
|
|
163
|
+
```
|
|
164
|
+
如果命令执行后输出中包含 HTML 标签(如 `<html`、`<!DOCTYPE`)而非正常 JSON 处理日志,说明是权限问题,参考上方「Medusa 权限问题诊断」停止并引导用户。
|
|
165
|
+
|
|
166
|
+
2. **执行检查命令**
|
|
167
|
+
```bash
|
|
168
|
+
npx i18n check --skip-confirm
|
|
169
|
+
```
|
|
170
|
+
命令执行后有两种结果:
|
|
171
|
+
- **输出行数 <= 100**:直接将控制台输出解析结果,**不会**生成 JSON 文件
|
|
172
|
+
- **输出行数 > 100**:在项目根目录生成 `check-result-{timestamp}.json`,控制台只打印概要
|
|
173
|
+
|
|
174
|
+
可选参数:
|
|
175
|
+
- `--auto-delete-unused`:自动删除未使用的 key
|
|
176
|
+
- `--summary-only`:只输出各语言缺失 key 数量统计,跳过删除和文件生成
|
|
177
|
+
|
|
178
|
+
3. **读取结果**
|
|
179
|
+
检查命令完成后,用 Glob 工具搜索项目根目录下的 `check-result-*.json`,取**最新的**一个读取。
|
|
180
|
+
JSON 文件结构如下:
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"timestamp": "...",
|
|
184
|
+
"summary": {
|
|
185
|
+
"totalMissingKeys": 0,
|
|
186
|
+
"totalUnusedKeys": 0,
|
|
187
|
+
"totalUntranslatedTexts": 0,
|
|
188
|
+
"totalOutputLines": 0
|
|
189
|
+
},
|
|
190
|
+
"missingKeys": { "zhCN": [], "enUS": [] },
|
|
191
|
+
"unusedKeys": { "zhCN": [], "enUS": [] },
|
|
192
|
+
"untranslatedTexts": []
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
如果没有 JSON 文件(输出行数 <= 100),则从控制台输出中解析以下信息:
|
|
196
|
+
- 各语言缺失的 key 数量(`zh-cn.json 缺失: N`)
|
|
197
|
+
- 未翻译的中文文案数量(`未翻译的中文文案: N 条`)
|
|
198
|
+
4. **向用户展示概要并询问下一步**
|
|
199
|
+
用简洁的 Markdown 展示检查结果,然后使用 AskQuestion 询问用户(**可多选**)希望进行哪些后续操作:
|
|
200
|
+
- 「增量翻译未翻译的中文文案(运行 patch 工作流)」
|
|
201
|
+
- 「暂不处理,我自己看结果」
|
|
202
|
+
5. **根据用户选择执行对应工作流**
|
|
203
|
+
|
|
204
|
+
## 修改文案:更新指定 key 的中英文并同步美杜莎
|
|
205
|
+
|
|
206
|
+
**重要:修改文案也必须通过美杜莎平台,不要直接修改本地 locale JSON 文件。**
|
|
89
207
|
|
|
90
208
|
### 步骤
|
|
91
209
|
|
|
92
|
-
1.
|
|
210
|
+
1. **解析用户意图**
|
|
211
|
+
|
|
212
|
+
从用户消息中提取 `key`、各语言新值(可选,如 `zhValue`、`enValue`)。如果用户只提供了部分信息,主动询问缺失的内容。
|
|
93
213
|
|
|
94
|
-
|
|
214
|
+
2. **读取现有文案并构造 payload**
|
|
95
215
|
|
|
96
|
-
|
|
216
|
+
从 `i18n.config.js` 的 `localesFilePath` 目录下读取各语言 JSON 文件,获取该 key 的现有值。
|
|
97
217
|
|
|
98
|
-
|
|
218
|
+
将要更新的内容构造成 `mds-payload.json` 格式:
|
|
99
219
|
|
|
220
|
+
```json
|
|
221
|
+
[
|
|
222
|
+
{
|
|
223
|
+
"key": "<key>",
|
|
224
|
+
"appName": "<medusa.appName>",
|
|
225
|
+
"i18n": {
|
|
226
|
+
"zh_CN": "<zh 值>",
|
|
227
|
+
"en_US": "<en 值>"
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
]
|
|
100
231
|
```
|
|
101
|
-
|
|
232
|
+
|
|
233
|
+
> `i18n` 对象中只包含**本次要更新的语言**,不要写入未修改的语言。
|
|
234
|
+
>
|
|
235
|
+
> 语言 key 使用下划线格式:`zh_CN`、`en_US`。
|
|
236
|
+
|
|
237
|
+
将文件写入项目根目录的 `mds-payload.json`。
|
|
238
|
+
|
|
239
|
+
3. **调用同步脚本上传到美杜莎**
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
node <SKILL_DIR>/scripts/sync-to-mds.js --env pre --yes
|
|
102
243
|
```
|
|
103
244
|
|
|
104
|
-
>
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
使用 `wait_for` 等待 `en_US` 或 `zh_CN` 文本出现(它会自动返回快照,无需再调 `take_snapshot`)。从快照中识别:
|
|
112
|
-
- `zh_CN` textarea、`en_US` textarea 的 uid
|
|
113
|
-
- 标签区域是否已有 `do_not_trans`
|
|
114
|
-
- 「保存」按钮 uid
|
|
115
|
-
|
|
116
|
-
**只修改用户指定的语言**,未指定的不要动。按以下顺序操作:
|
|
117
|
-
|
|
118
|
-
a. **填入文案** — 对每个需要修改的 textarea,通过 `evaluate_script` 设置值(可以在**一次调用**中同时处理多个 textarea):
|
|
119
|
-
```javascript
|
|
120
|
-
(zh, en) => {
|
|
121
|
-
const set = (el, v) => {
|
|
122
|
-
if (!el || v === null) return;
|
|
123
|
-
const setter = Object.getOwnPropertyDescriptor(window.HTMLTextAreaElement.prototype, 'value').set;
|
|
124
|
-
setter.call(el, v);
|
|
125
|
-
el.dispatchEvent(new Event('input', { bubbles: true }));
|
|
126
|
-
el.dispatchEvent(new Event('change', { bubbles: true }));
|
|
127
|
-
};
|
|
128
|
-
set(zh, '新中文值或null');
|
|
129
|
-
set(en, '新英文值或null');
|
|
130
|
-
return 'ok';
|
|
131
|
-
}
|
|
132
|
-
```
|
|
133
|
-
> 不需要修改的语言传 `null`,对应 `args` 中仍需传一个占位 uid(任意元素即可)。
|
|
134
|
-
|
|
135
|
-
b. **添加 do_not_trans 标签**(如果快照中已有则**跳过此步**) — 通过 `evaluate_script` 一次完成:
|
|
136
|
-
```javascript
|
|
137
|
-
(combobox) => {
|
|
138
|
-
combobox.click();
|
|
139
|
-
return new Promise(resolve => {
|
|
140
|
-
setTimeout(() => {
|
|
141
|
-
const opt = [...document.querySelectorAll('[role="option"]')].find(el => el.textContent.trim() === 'do_not_trans');
|
|
142
|
-
if (opt) opt.click();
|
|
143
|
-
setTimeout(() => {
|
|
144
|
-
combobox.blur();
|
|
145
|
-
document.body.click();
|
|
146
|
-
resolve('done');
|
|
147
|
-
}, 200);
|
|
148
|
-
}, 300);
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
c. **保存并发布** — 点击「保存」按钮,紧接着点击「立即发布」按钮(无需等待保存成功提示,两次 click 可连续调用),然后结束流程,等待用户手动确认即可。
|
|
245
|
+
> `<SKILL_DIR>` 替换为本 SKILL.md 所在目录相对于项目根目录的路径(如 `.cursor/skills/i18n-helper`)。
|
|
246
|
+
|
|
247
|
+
脚本会自动写入美杜莎、发布,并在完成后删除 `mds-payload.json`。
|
|
248
|
+
|
|
249
|
+
> **【安全规则】永远不要对 prod 环境使用 `--yes`**。如果用户明确要求写入 prod,去掉 `--yes`,让用户在终端手动确认冲突。
|
|
250
|
+
|
|
251
|
+
**如果脚本报错或返回 HTML 而非 JSON**,参考上方「Medusa 权限问题诊断」引导用户申请权限。
|
|
154
252
|
|
|
253
|
+
4. **同步完成后更新本地 locale 文件**
|
|
254
|
+
|
|
255
|
+
运行以下命令从美杜莎拉取最新翻译到本地,确保本地文件与平台一致:
|
|
256
|
+
```bash
|
|
257
|
+
npx i18n medusa
|
|
258
|
+
```
|
|
155
259
|
|
|
156
260
|
## 注意事项
|
|
157
261
|
|
|
158
|
-
-
|
|
262
|
+
- **静默执行**:执行过程中不要输出中间状态描述,直接操作即可。仅在最终完成或出错时输出一句简短结果
|
|
159
263
|
- 美杜莎是阿里内网平台,需要连接内网/VPN 才能访问
|
|
160
|
-
-
|
|
264
|
+
- 美杜莎后端地址:`https://wanx-medusa-config.pre-fn.alibaba-inc.com/`
|
|
161
265
|
- key 中不支持模板字符串或表达式,全部使用字符串字面量
|
|
162
|
-
- 忽略翻译可使用注释:`// @i18n-ignore`(文件级)、`// @i18n-ignore-line`(行级)、`// @i18n-ignore-block-start/end`(块级)
|
|
266
|
+
- 忽略翻译可使用注释:`// @i18n-ignore`(文件级)、`// @i18n-ignore-line`(行级)、`// @i18n-ignore-block-start/end`(块级)
|