dsh-cait 1.0.3 → 1.0.4

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.zh-CN.md CHANGED
@@ -1,390 +1,391 @@
1
- <p align="center">
2
- <img src="icon.svg" width="76" alt="CAIT 图标" />
3
- </p>
4
-
5
- <h1 align="center">CAIT</h1>
6
-
7
- <p align="center">
8
- <strong>在 DeepSeek Harness 中完成计算机辅助翻译。</strong><br/>
9
- 翻译记忆 · 术语库 · 句段编辑器 · 机器翻译辅助 · 文档标签页 · Office / 字幕 / 本地化格式
10
- </p>
11
-
12
- <p align="center">
13
- <a href="README.md">English</a> · <a href="README.zh-CN.md">简体中文</a> · <a href="README.ja.md">日本語</a>
14
- </p>
15
-
16
- <p align="center">
17
- <img alt="版本 1.0.3" src="https://img.shields.io/badge/version-1.0.3-blue.svg" />
18
- <img alt="DSH 0.2.x" src="https://img.shields.io/badge/DSH-0.2.x-4d6bfe.svg" />
19
- <img alt="13 套测试" src="https://img.shields.io/badge/tests-13%20suites-brightgreen.svg" />
20
- <img alt="无需 API Key" src="https://img.shields.io/badge/API%20key-not%20required-6b7280.svg" />
21
- </p>
22
-
23
- CAIT 为 DSH Web UI 和 DSH 桌面端增加一个 CAT 翻译工作台。它从左侧栏入口打开,
24
- 工作台与七个 Agent 工具共用一个数据存储,覆盖从导入源文件到导出译文的完整流程。
25
-
26
- > **已在 DSH `0.2.2-rc.1` 中验证。** CAIT 使用 DSH 自己的模型路由和凭据,
27
- > 不会要求用户填写 API Key。内部回退提供方仍叫 `mock`,界面显示为
28
- > **术语替换(离线)**。
29
-
30
- ## 为什么选择 CAIT
31
-
32
- | | |
33
- |---|---|
34
- | **原生集成 DSH** | 真正的侧栏入口、主工作台、DSH 主题令牌,以及人和 Agent 共用的同一份数据。不是 iframe,也不是另一个独立应用。 |
35
- | **可解释的翻译记忆** | 支持多个 TM 库、仅检索已挂载库、精确/近似精确/高/中/低模糊等级,确认句段时自动写回。 |
36
- | **术语感知编辑** | 支持多个术语库、按源语言过滤、行内高亮、点击插入术语,以及按术语设置是否区分大小写。 |
37
- | **完整文档流程** | 文档标签页、关闭/重新打开、最近文档清理、重复导入复用、逐文档进度。 |
38
- | **真实格式覆盖** | TXT、Markdown、DOCX、TMX、CSV、SRT/VTT、PO、XLIFF 1.2/2.0/SDLXLIFF、HTML、JSON、XLSX、PPTX、RTF。 |
39
- | **面向 Agent** | 七个工具共享当前文档和存储,Agent 可以与用户同时翻译。 |
40
-
41
- ## 快速开始
42
-
43
- 1. 安装 CAIT,然后从左侧栏的 **CAIT** 入口打开。
44
- 2. 选择 **新开页面**,拖入源文件或粘贴文本。
45
- 3. 设置源语言和目标语言。
46
- 4. 翻译当前句段;右侧面板会显示 TM 匹配、术语命中和 MT 建议。
47
- 5. 点击 **确认并下一句**,句对会写入默认挂载的 TM。
48
- 6. 导出纯译文、双语对照,或保留源格式的文档。
49
-
50
- 编辑器中的输入只是草稿,保存在内存里。确认句段(或执行明确的结构性修改)时
51
- 才会写入快照。打开的工作台每两秒轮询一次 Host revision,因此 Agent 触发的修改
52
- 无需手动刷新即可出现。
53
-
54
- ## 功能
55
-
56
- ### 翻译记忆
57
-
58
- - 支持多个 TM 库,每个库有 id、名称、挂载状态和默认写入库。
59
- - 支持精确、近似精确和三个模糊等级:
60
- - `near_exact` 使用忽略数字、标点和空白后的 key 比较,不依赖分数阈值。
61
- - `high_fuzzy` 为 `>= 0.85`,`medium_fuzzy` 为 `0.75–0.85`,
62
- `low_fuzzy` 低于 `0.75`(高于可配置下限,默认 `0.55`)。
63
- - 模糊评分是词法级的:72% 字符二元组 Dice + 28% token Jaccard。
64
- 拉丁文本按单词切分,CJK 文本按单字切分;不做词干、同义词或语义匹配。
65
- - 检索只查已挂载的库。`cat_submit_translation` 支持可选 `targetTmId`;
66
- 未挂载的目标库会以 `TM_NOT_MOUNTED` 拒绝写入。
67
- - `bootstrap().tm.entries` 是已挂载条目的 40 条预览;
68
- `bootstrap().tm.count` 是已挂载数量,`bootstrap().tm.total` 是所有库的总数。
69
- 完整数据请使用 `cat_lookup_tm` 或库面板。
70
- - 支持 TMX 1.4 `<tu>/<tuv>/<seg>` 导入/导出。TMX 内联占位符会扁平化为
71
- 纯文本,并给出明确警告。
72
-
73
- ### 术语库
74
-
75
- - 支持多个术语库,每个库有挂载状态和默认写入库。
76
- - 源文行内高亮,点击术语 chip 即可插入。
77
- - 支持 CSV/TSV 导入、术语备注、源语言过滤,以及工作台和
78
- `cat_lookup_glossary` 都遵循的 `caseSensitive` 标记。
79
- - 语言代码会规范化(`EN` → `en`,`ZH_cn` → `zh-CN`)。
80
-
81
- ### 工作台
82
-
83
- - 按段落/句子切分,并逐句编辑译文。
84
- - 支持保存草稿、确认并下一句、上一句/下一句导航和进度。
85
- - 文档标签页;关闭标签页不会删除文档。
86
- - **打开已有文档** 可重新打开已关闭的文档。
87
- - **设置 → 界面** 提供界面语言切换:跟随 DSH 语言(默认)、简体中文、English、
88
- 日本語。工作台与侧栏名称立即生效,且只改 CAIT 界面,不会改动文档的源语言或
89
- 目标语言。
90
- - 下拉框旁的垃圾桶按钮可删除一个或全部已关闭文档;删除是永久性的,
91
- 不会影响 TM、术语库或其他文档。
92
- - 同格式、同内容的再次导入会复用已有文档,而不是新建重复文档。
93
- 指纹覆盖语言、源文、格式和交换元数据。
94
- - 响应式密度:工作台测量自身 DSH 面板,并应用 1×–1.8× 的 `--cait-u`
95
- 缩放系数。1600×900 面板约为 1.32×,2560×1440 面板为 1.8×;
96
- 窗口较矮时保持 1×,不会继续缩小。
97
-
98
- ### MT 辅助
99
-
100
- CAIT 不持有 endpoint 或 key,选择器完全来自 DSH:
101
-
102
- - `ctx.llm.listProviders()` 提供已注册的提供方路由。
103
- - 可用时通过 `ctx.loader.entries()` 查询 `config.providers`。
104
- - `ctx.llm.listModels(provider)` 提供模型 id;CAIT 默认选择第一个模型。
105
- - `ctx.llm.stream({ provider, model, messages, temperature, purpose: 'cait-mt' })`
106
- 执行调用;CAIT 只拼接 `text-delta` chunk。
107
-
108
- 如果没有可用路由、所选路由消失或没有模型,CAIT 会回退到离线术语替换,
109
- 并在 UI 和 `cat_suggest_mt` 结果中明确说明。流式调用失败时,Host 日志记录
110
- provider/model/code/status,客户端只会收到 `MT_PROVIDER_FAILED`。
111
-
112
- ## 支持的格式
113
-
114
- | 格式 | 导入 | 导出 | 说明 |
115
- | --- | :---: | :---: | --- |
116
- | TXT / Markdown | ✅ | ✅ | 按段落和句子切分 |
117
- | CSV | ✅ | ✅ | 可通过表头名称或从 1 开始的列号指定源/目标列;现有双语导出 |
118
- | DOCX | ✅ | ✅ | 正文段落;导入时排除表格块。导出会修改原包,保留样式、编号、图片、页眉、表格和版式。 |
119
- | TMX 1.4 | ✅ | ✅ | 常见 `<tu>/<tuv>/<seg>` 子集;内联标记扁平化并警告 |
120
- | SRT / WebVTT | ✅ | ✅ | 一个字幕 cue 对应一个句段;保留时间轴/设置/标识;保留语义标签;非法时间范围会拒绝 |
121
- | PO | ✅ | ✅ | 支持上下文、复数形式、译者注释和废弃 `#~` 条目 |
122
- | XLIFF 1.2 | ✅ | ✅ | 内联标签转换为 `{n}` token;缺少 token 时阻止确认 |
123
- | XLIFF 2.0 | ✅ | ✅ | 基础 `<unit><segment><source>/<target>` 子集 |
124
- | SDLXLIFF | ✅ | ✅ | 走基础 XLIFF 1.2 路径;SDL 专有扩展不会完整往返 |
125
- | HTML | ✅ | ✅ | 仅文本块;不保留原始标记/CSS |
126
- | JSON | ✅ | ✅ | 字符串路径子集;通过模板保留对象/数组结构;key 和数字不翻译 |
127
- | XLSX | ✅ | ✅ | 第一个工作表;识别 `Source`/`Target` 表头或 A/B 列;导出为新的两列表格 |
128
- | PPTX | ✅ | ✅* | 保留源格式导出;需要导入时保留的 `.pptx` 包。仅正文;备注/图表/SmartArt 不导入。 |
129
- | RTF | ✅ | ✅ | 基础段落、`\uN`、`\'hh`、控制字;不往返原始样式 |
130
-
131
- \* 如果保留的源包不存在,PPTX 导出会以 `PPTX_SOURCE_REQUIRED` 失败,
132
- 而不是静默生成一个没有格式的演示文稿。
133
-
134
- 交换元数据(字幕时间轴、PO 上下文/复数/注释、XLIFF id 和内联 token 映射、
135
- JSON 路径/模板、XLSX 行号、PPTX 幻灯片/段落位置)会保存在文档/句段上,
136
- 并随快照持久化。
137
-
138
- ## 安装
139
-
140
- CAIT 以 DSH bundle 的形式安装;发布的 npm 包名为 `dsh-cait`,插件本身在左侧栏显示为
141
- **CAIT**。`desktop` 配置档由应用的 plugin manager 管理,请通过它安装,不要手写配置档的
142
- `package.json`。
143
-
144
- ### 从 npm 安装
145
-
146
- 在 DSH 桌面端(或任何带有 `plugin_manager` 工具的配置档)中:
147
-
148
- ```text
149
- plugin_manager install_bundle target: dsh-cait
150
- ```
151
-
152
- 需要固定版本时写 `dsh-cait@1.0.3`,需要最新版时写 `dsh-cait@latest`。管理器会解析 registry
153
- 上的包、应用 bundle patch 并激活插件,不需要手工在配置档里加行。
154
-
155
- 使用 CLI 管理的配置档:
156
-
157
- ```sh
158
- dsh plugin --profile web add dsh-cait
159
- ```
160
-
161
- 将 `web` 替换为你的配置档名称。如果 Host 需要重启,请重启 `dsh web`。
162
-
163
- ### 从本仓库安装
164
-
165
- GitHub:
166
-
167
- ```text
168
- plugin_manager install_bundle target: github:JoviLecca/dsh-CAIT
169
- ```
170
-
171
- 本地目录:
172
-
173
- ```text
174
- plugin_manager install_bundle target: /absolute/path/to/dsh-CAIT
175
- ```
176
-
177
- 然后重新加载 DSH。左侧栏会出现 **CAIT** 入口。
178
-
179
- ### 从源码安装
180
-
181
- ```sh
182
- git clone <this-repository> dsh-CAIT
183
- cd dsh-CAIT
184
- npm run build:client
185
- ```
186
-
187
- 本地 `--patch` 覆盖层可以添加一行指向当前目录:
188
-
189
- ```yaml
190
- # _dev/cait.patch.yml
191
- - insert:
192
- - id: cait-dev
193
- name: 'C:\absolute\path\to\dsh-CAIT'
194
- ```
195
-
196
- ```powershell
197
- dsh web --patch C:\absolute\path\to\dsh-CAIT\_dev\cait.patch.yml
198
- ```
199
-
200
- `--patch` 是启动器选项;放在应用名(`web`)之后、应用自身参数之前。
201
- 覆盖层和配置档中已安装的 bundle 二选一,不要同时使用。
202
-
203
- ## 配置
204
-
205
- | 选项 | 默认值 | 含义 |
206
- | --- | --- | --- |
207
- | `dataDir` | `""` | `store.json` 和 `sources/` 的目录。为空时使用 `$DSH_HOME/cait`。支持绝对路径、相对路径和 `~/...`。 |
208
-
209
- ```yaml
210
- - id: dsh-cait
211
- name: dsh-cait
212
- config:
213
- dataDir: 'D:\CAT\cait-data'
214
- ```
215
-
216
- 快照保存文档、打开的标签页、TM、术语库、库、挂载关系和非敏感设置。
217
- 导入的 DOCX/PPTX 源包放在 `sources/` 下。
218
-
219
- 界面内的**设置**保存在快照里,而不是上面的 YAML:源语言/目标语言、模糊阈值、
220
- TM 返回条数、MT 路由/模型/温度,以及界面语言(`uiLang`:`auto` | `zh` | `en` |
221
- `ja`,默认 `auto` 即跟随 DSH 语言)。
222
-
223
- 句段确认使用严格写入:如果快照无法写入,确认会以 `PERSISTENCE_FAILED`(503)
224
- 失败,并回滚内存中的确认。其他结构性修改采用尽力写入,并通过工作台横幅显示
225
- `bootstrap().storage.error`。
226
-
227
- 如果快照损坏或版本未知,CAIT 会记录警告,将其移动到
228
- `store.json.corrupt-<timestamp>`,然后以空状态启动,而不是让插件激活失败。
229
- 版本 1 快照会迁移到版本 2,并创建默认 TM 和术语库。
230
-
231
- ## Agent 工具
232
-
233
- | 工具 | 用途 |
234
- | --- | --- |
235
- | `cat_get_segment` | 获取当前句段及 TM 匹配、术语命中 |
236
- | `cat_submit_translation` | 确认译文,写入已挂载 TM(可选 `targetTmId`),前进到下一句 |
237
- | `cat_lookup_tm` | 在已挂载库中按等级检索 TM |
238
- | `cat_lookup_glossary` | 查询已挂载术语库;遵循 `caseSensitive` |
239
- | `cat_list_documents` | 列出文档和进度 |
240
- | `cat_switch_document` | 选择活动文档 |
241
- | `cat_suggest_mt` | 通过所选 DSH 路由调用 MT,或使用明确的离线回退 |
242
-
243
- 工作台和工具共用一个 `CatStore`,因此 Agent 可以翻译用户当前打开的同一份文档。
244
-
245
- ## 架构
246
-
247
- ```mermaid
248
- flowchart LR
249
- UI["DSH Web UI<br/>(侧栏 + 工作台)"] --> Client["client.js<br/>生成的 Web bundle"]
250
- Client --> API["/cait/api/rpc<br/>同源 JSON"]
251
- Tools["7 个 Agent 工具"] --> Store["CatStore"]
252
- API --> Store
253
- Store --> Snapshot[("store.json<br/>+ sources/")]
254
- ```
255
-
256
- - **Host**(`index.js`、`lib/`)负责存储、持久化、导入/导出、工具和私有 API。
257
- - **Client**(`client/`)是通过 DSH 模块加载器加载的普通 React,渲染到
258
- `sidebar.panellist` 和 `main`。样式只使用 `--dsw-alias-*` 令牌。
259
- - `client.js` 是生成文件;请修改 `client/*.js`,然后运行 `npm run build:client`。
260
-
261
- <details>
262
- <summary><strong>项目结构</strong></summary>
263
-
264
- ```text
265
- cait/
266
- ├─ package.json
267
- ├─ cordis.patch.yml
268
- ├─ index.js # Host 端
269
- ├─ client.js # 生成的 Web bundle
270
- ├─ client/ # helpers、styles、RPC、components、locales、entry
271
- ├─ scripts/build-client.mjs
272
- ├─ icon.svg
273
- ├─ locale/{en,zh,ja}.json
274
- ├─ NOTICE
275
- ├─ README.md
276
- ├─ README.zh-CN.md
277
- ├─ README.ja.md
278
- ├─ CHANGELOG.md
279
- ├─ lib/
280
- │ ├─ store.js # CatStore 门面 + 文档/句段核心
281
- │ ├─ errors.js
282
- │ ├─ store-utils.js
283
- │ ├─ libraries.js # TM/术语库注册表 + 挂载
284
- │ ├─ tm.js
285
- │ ├─ glossary.js
286
- │ ├─ persistence.js
287
- │ ├─ import-export.js
288
- │ ├─ formats.js # CSV/SRT/VTT/PO/XLIFF/HTML/JSON/RTF
289
- │ ├─ xlsx.js
290
- │ ├─ pptx.js
291
- │ ├─ segmenter.js
292
- │ ├─ similarity.js
293
- │ ├─ tmx.js
294
- │ ├─ docx.js
295
- │ ├─ markdown.js
296
- │ ├─ xml.js
297
- │ ├─ mt.js
298
- │ ├─ tools.js
299
- │ └─ api.js
300
- └─ _dev/ # 测试、fixture、本地 patch 覆盖层
301
- ```
302
-
303
- </details>
304
-
305
- ## 开发
306
-
307
- 需要 Node.js 22+ 和 DSH `0.2.x`。已在 DSH `0.2.2-rc.1`、Node `26.7.0`
308
- 中测试。
309
-
310
- ```sh
311
- npm run build:client
312
- node --check client.js
313
-
314
- node _dev/test-core.mjs
315
- node _dev/test-imports.mjs
316
- node _dev/test-formats.mjs
317
- node _dev/test-second-tier.mjs
318
- node _dev/test-docx-export.mjs
319
- node _dev/test-api.mjs
320
- node _dev/test-plugin.mjs
321
- node _dev/test-persistence.mjs
322
- node _dev/test-documents.mjs
323
- node _dev/test-libraries.mjs
324
- node _dev/test-mounts.mjs
325
- node _dev/test-ui-scale.mjs
326
- node _dev/test-mt.mjs
327
- ```
328
-
329
- 导入/导出 fixture 为 `_dev/sample.docx`、`_dev/sample-table.docx` 和
330
- `_dev/sample-format.docx`;可用对应的 `python _dev/make-*.py` 脚本重新生成。
331
- 13 套测试应全部通过。
332
-
333
- ### 发布
334
-
335
- `npm publish` 会触发 `prepublishOnly`:从 `client/` 的片段重建 `client.js`
336
- 并做语法检查,因此发布出去的不会是一个过期的 bundle。在仓库根目录执行:
337
-
338
- ```sh
339
- npm publish
340
- ```
341
-
342
- `.github/workflows/publish.yml` 会在 GitHub 发布 release 时做同样的事,使用
343
- npm Trusted Publishing(OIDC)而不是保存的 token,并且当 release tag 与
344
- `package.json` 的版本不一致时拒绝发布。
345
-
346
- 首次发布必须在本地完成,因为 Trusted Publishing 只能为已经存在的包配置:
347
-
348
- ```sh
349
- npm login
350
- npm publish
351
- ```
352
-
353
- 之后在 npmjs.com 打开该包,进入 **Settings → Trusted publishing**,添加仓库
354
- `JoviLecca/dsh-CAIT` 和 workflow 文件 `publish.yml`。以后的版本就可以通过
355
- GitHub release 发布。
356
-
357
- ## 安全模型
358
-
359
- - Host API 挂载在 `/cait/api`,通过 `ctx.connection.requestRejection`
360
- 限制为同源/受信任请求。
361
- - RPC 请求体为 JSON,上限 32 MB;超过时返回 `413 BODY_TOO_LARGE`。
362
- - `clearTM` / `clearGlossary` 除了浏览器信任检查外,还要求
363
- `params.confirm === true`;UI 会在发送前询问。
364
- - CAIT 从不接收、存储或返回 API Key。DSH 凭据保留在所选提供方适配器内部。
365
- - 持久化使用单个快照,语义为最后写入者获胜;它不是多用户日志。
366
-
367
- ## 已知限制与路线图
368
-
369
- - 暂不支持 PDF、EPUB 或图片 OCR 导入。
370
- - DOCX 导入会跳过表格、页眉、脚注、域、替代文本和修订删除内容。
371
- DOCX 导出时这些区域保持源语言。
372
- - DOCX/PPTX 中混合 run 的段落会继承第一个 run 的格式。
373
- - PPTX 导入只覆盖正文,不包含备注、图表或 SmartArt。
374
- - XLSX 导入/导出是两列表格;不保留单元格样式、公式、合并单元格、图片和额外工作表。
375
- - HTML/RTF 导出不往返原始样式;JSON 只翻译字符串值。
376
- - TM 匹配是词法级的,不是语义级;没有词干、同义词或向量。
377
- - 库重命名/删除和逐标签页挂载状态不属于 v1.0.0。
378
- - 工作台界面提供中文、English、日本語三种语言,可在设置中切换;README 提供英文、简体中文和日文三个版本,以英文版为准。
379
-
380
- 后续计划:PDF 与 EPUB 适配器、通过多模态 DSH 路由支持图片/视觉输入、
381
- 更完整的库管理、保留样式的 XLSX 输出,以及 XLIFF `<alt-trans>` / 注释支持。
382
-
383
- ## 变更日志与版本
384
-
385
- 见 [CHANGELOG.md](CHANGELOG.md)。`v1.0.0` 是首个公开发布版本,`v1.0.1` 增加了
386
- 日语界面和界面内语言切换,`v1.0.2` 让「跟随 DSH 语言」真正跟随 DSH 的语言设置,
387
- `v1.0.3` 把包发布到 npm;项目在开发阶段使用 `0.1.0`,发布到 GitHub 前统一改为 `1.0.0`。
388
-
389
- > **License:** Apache License 2.0,见 [LICENSE](LICENSE)。再分发时需保留
390
- > [NOTICE](NOTICE) 中的署名信息。
1
+ <p align="center">
2
+ <img src="icon.svg" width="76" alt="CAIT 图标" />
3
+ </p>
4
+
5
+ <h1 align="center">CAIT</h1>
6
+
7
+ <p align="center">
8
+ <strong>在 DeepSeek Harness 中完成计算机辅助翻译。</strong><br/>
9
+ 翻译记忆 · 术语库 · 句段编辑器 · 机器翻译辅助 · 文档标签页 · Office / 字幕 / 本地化格式
10
+ </p>
11
+
12
+ <p align="center">
13
+ <a href="README.md">English</a> · <a href="README.zh-CN.md">简体中文</a> · <a href="README.ja.md">日本語</a>
14
+ </p>
15
+
16
+ <p align="center">
17
+ <a href="https://www.npmjs.com/package/dsh-cait"><img alt="npm 版本" src="https://img.shields.io/npm/v/dsh-cait.svg" /></a>
18
+ <img alt="DSH 0.2.x" src="https://img.shields.io/badge/DSH-0.2.x-4d6bfe.svg" />
19
+ <img alt="13 套测试" src="https://img.shields.io/badge/tests-13%20suites-brightgreen.svg" />
20
+ <img alt="无需 API Key" src="https://img.shields.io/badge/API%20key-not%20required-6b7280.svg" />
21
+ </p>
22
+
23
+ CAIT 为 DSH Web UI 和 DSH 桌面端增加一个 CAT 翻译工作台。它从左侧栏入口打开,
24
+ 工作台与七个 Agent 工具共用一个数据存储,覆盖从导入源文件到导出译文的完整流程。
25
+
26
+ > **已在 DSH `0.2.2-rc.1` 中验证。** CAIT 使用 DSH 自己的模型路由和凭据,
27
+ > 不会要求用户填写 API Key。内部回退提供方仍叫 `mock`,界面显示为
28
+ > **术语替换(离线)**。
29
+
30
+ ## 为什么选择 CAIT
31
+
32
+ | | |
33
+ |---|---|
34
+ | **原生集成 DSH** | 真正的侧栏入口、主工作台、DSH 主题令牌,以及人和 Agent 共用的同一份数据。不是 iframe,也不是另一个独立应用。 |
35
+ | **可解释的翻译记忆** | 支持多个 TM 库、仅检索已挂载库、精确/近似精确/高/中/低模糊等级,确认句段时自动写回。 |
36
+ | **术语感知编辑** | 支持多个术语库、按源语言过滤、行内高亮、点击插入术语,以及按术语设置是否区分大小写。 |
37
+ | **完整文档流程** | 文档标签页、关闭/重新打开、最近文档清理、重复导入复用、逐文档进度。 |
38
+ | **真实格式覆盖** | TXT、Markdown、DOCX、TMX、CSV、SRT/VTT、PO、XLIFF 1.2/2.0/SDLXLIFF、HTML、JSON、XLSX、PPTX、RTF。 |
39
+ | **面向 Agent** | 七个工具共享当前文档和存储,Agent 可以与用户同时翻译。 |
40
+
41
+ ## 快速开始
42
+
43
+ 1. 安装 CAIT,然后从左侧栏的 **CAIT** 入口打开。
44
+ 2. 选择 **新开页面**,拖入源文件或粘贴文本。
45
+ 3. 设置源语言和目标语言。
46
+ 4. 翻译当前句段;右侧面板会显示 TM 匹配、术语命中和 MT 建议。
47
+ 5. 点击 **确认并下一句**,句对会写入默认挂载的 TM。
48
+ 6. 导出纯译文、双语对照,或保留源格式的文档。
49
+
50
+ 编辑器中的输入只是草稿,保存在内存里。确认句段(或执行明确的结构性修改)时
51
+ 才会写入快照。打开的工作台每两秒轮询一次 Host revision,因此 Agent 触发的修改
52
+ 无需手动刷新即可出现。
53
+
54
+ ## 功能
55
+
56
+ ### 翻译记忆
57
+
58
+ - 支持多个 TM 库,每个库有 id、名称、挂载状态和默认写入库。
59
+ - 支持精确、近似精确和三个模糊等级:
60
+ - `near_exact` 使用忽略数字、标点和空白后的 key 比较,不依赖分数阈值。
61
+ - `high_fuzzy` 为 `>= 0.85`,`medium_fuzzy` 为 `0.75–0.85`,
62
+ `low_fuzzy` 低于 `0.75`(高于可配置下限,默认 `0.55`)。
63
+ - 模糊评分是词法级的:72% 字符二元组 Dice + 28% token Jaccard。
64
+ 拉丁文本按单词切分,CJK 文本按单字切分;不做词干、同义词或语义匹配。
65
+ - 检索只查已挂载的库。`cat_submit_translation` 支持可选 `targetTmId`;
66
+ 未挂载的目标库会以 `TM_NOT_MOUNTED` 拒绝写入。
67
+ - `bootstrap().tm.entries` 是已挂载条目的 40 条预览;
68
+ `bootstrap().tm.count` 是已挂载数量,`bootstrap().tm.total` 是所有库的总数。
69
+ 完整数据请使用 `cat_lookup_tm` 或库面板。
70
+ - 支持 TMX 1.4 `<tu>/<tuv>/<seg>` 导入/导出。TMX 内联占位符会扁平化为
71
+ 纯文本,并给出明确警告。
72
+
73
+ ### 术语库
74
+
75
+ - 支持多个术语库,每个库有挂载状态和默认写入库。
76
+ - 源文行内高亮,点击术语 chip 即可插入。
77
+ - 支持 CSV/TSV 导入、术语备注、源语言过滤,以及工作台和
78
+ `cat_lookup_glossary` 都遵循的 `caseSensitive` 标记。
79
+ - 语言代码会规范化(`EN` → `en`,`ZH_cn` → `zh-CN`)。
80
+
81
+ ### 工作台
82
+
83
+ - 按段落/句子切分,并逐句编辑译文。
84
+ - 支持保存草稿、确认并下一句、上一句/下一句导航和进度。
85
+ - 文档标签页;关闭标签页不会删除文档。
86
+ - **打开已有文档** 可重新打开已关闭的文档。
87
+ - **设置 → 界面** 提供界面语言切换:跟随 DSH 语言(默认)、简体中文、English、
88
+ 日本語。工作台与侧栏名称立即生效,且只改 CAIT 界面,不会改动文档的源语言或
89
+ 目标语言。
90
+ - 下拉框旁的垃圾桶按钮可删除一个或全部已关闭文档;删除是永久性的,
91
+ 不会影响 TM、术语库或其他文档。
92
+ - 同格式、同内容的再次导入会复用已有文档,而不是新建重复文档。
93
+ 指纹覆盖语言、源文、格式和交换元数据。
94
+ - 响应式密度:工作台测量自身 DSH 面板,并应用 1×–1.8× 的 `--cait-u`
95
+ 缩放系数。1600×900 面板约为 1.32×,2560×1440 面板为 1.8×;
96
+ 窗口较矮时保持 1×,不会继续缩小。
97
+
98
+ ### MT 辅助
99
+
100
+ CAIT 不持有 endpoint 或 key,选择器完全来自 DSH:
101
+
102
+ - `ctx.llm.listProviders()` 提供已注册的提供方路由。
103
+ - 可用时通过 `ctx.loader.entries()` 查询 `config.providers`。
104
+ - `ctx.llm.listModels(provider)` 提供模型 id;CAIT 默认选择第一个模型。
105
+ - `ctx.llm.stream({ provider, model, messages, temperature, purpose: 'cait-mt' })`
106
+ 执行调用;CAIT 只拼接 `text-delta` chunk。
107
+
108
+ 如果没有可用路由、所选路由消失或没有模型,CAIT 会回退到离线术语替换,
109
+ 并在 UI 和 `cat_suggest_mt` 结果中明确说明。流式调用失败时,Host 日志记录
110
+ provider/model/code/status,客户端只会收到 `MT_PROVIDER_FAILED`。
111
+
112
+ ## 支持的格式
113
+
114
+ | 格式 | 导入 | 导出 | 说明 |
115
+ | --- | :---: | :---: | --- |
116
+ | TXT / Markdown | ✅ | ✅ | 按段落和句子切分 |
117
+ | CSV | ✅ | ✅ | 可通过表头名称或从 1 开始的列号指定源/目标列;现有双语导出 |
118
+ | DOCX | ✅ | ✅ | 正文段落;导入时排除表格块。导出会修改原包,保留样式、编号、图片、页眉、表格和版式。 |
119
+ | TMX 1.4 | ✅ | ✅ | 常见 `<tu>/<tuv>/<seg>` 子集;内联标记扁平化并警告 |
120
+ | SRT / WebVTT | ✅ | ✅ | 一个字幕 cue 对应一个句段;保留时间轴/设置/标识;保留语义标签;非法时间范围会拒绝 |
121
+ | PO | ✅ | ✅ | 支持上下文、复数形式、译者注释和废弃 `#~` 条目 |
122
+ | XLIFF 1.2 | ✅ | ✅ | 内联标签转换为 `{n}` token;缺少 token 时阻止确认 |
123
+ | XLIFF 2.0 | ✅ | ✅ | 基础 `<unit><segment><source>/<target>` 子集 |
124
+ | SDLXLIFF | ✅ | ✅ | 走基础 XLIFF 1.2 路径;SDL 专有扩展不会完整往返 |
125
+ | HTML | ✅ | ✅ | 仅文本块;不保留原始标记/CSS |
126
+ | JSON | ✅ | ✅ | 字符串路径子集;通过模板保留对象/数组结构;key 和数字不翻译 |
127
+ | XLSX | ✅ | ✅ | 第一个工作表;识别 `Source`/`Target` 表头或 A/B 列;导出为新的两列表格 |
128
+ | PPTX | ✅ | ✅* | 保留源格式导出;需要导入时保留的 `.pptx` 包。仅正文;备注/图表/SmartArt 不导入。 |
129
+ | RTF | ✅ | ✅ | 基础段落、`\uN`、`\'hh`、控制字;不往返原始样式 |
130
+
131
+ \* 如果保留的源包不存在,PPTX 导出会以 `PPTX_SOURCE_REQUIRED` 失败,
132
+ 而不是静默生成一个没有格式的演示文稿。
133
+
134
+ 交换元数据(字幕时间轴、PO 上下文/复数/注释、XLIFF id 和内联 token 映射、
135
+ JSON 路径/模板、XLSX 行号、PPTX 幻灯片/段落位置)会保存在文档/句段上,
136
+ 并随快照持久化。
137
+
138
+ ## 安装
139
+
140
+ CAIT 以 DSH bundle 的形式安装;发布的 npm 包名为 `dsh-cait`,插件本身在左侧栏显示为
141
+ **CAIT**。`desktop` 配置档由应用的 plugin manager 管理,请通过它安装,不要手写配置档的
142
+ `package.json`。
143
+
144
+ ### 从 npm 安装
145
+
146
+ 在 DSH 桌面端(或任何带有 `plugin_manager` 工具的配置档)中:
147
+
148
+ ```text
149
+ plugin_manager install_bundle target: dsh-cait
150
+ ```
151
+
152
+ 需要固定版本时写 `dsh-cait@1.0.4`,需要最新版时写 `dsh-cait@latest`。管理器会解析 registry
153
+ 上的包、应用 bundle patch 并激活插件,不需要手工在配置档里加行。
154
+
155
+ 使用 CLI 管理的配置档:
156
+
157
+ ```sh
158
+ dsh plugin --profile web add dsh-cait
159
+ ```
160
+
161
+ 将 `web` 替换为你的配置档名称。如果 Host 需要重启,请重启 `dsh web`。
162
+
163
+ ### 从本仓库安装
164
+
165
+ GitHub:
166
+
167
+ ```text
168
+ plugin_manager install_bundle target: github:JoviLecca/dsh-CAIT
169
+ ```
170
+
171
+ 本地目录:
172
+
173
+ ```text
174
+ plugin_manager install_bundle target: /absolute/path/to/dsh-CAIT
175
+ ```
176
+
177
+ 然后重新加载 DSH。左侧栏会出现 **CAIT** 入口。
178
+
179
+ ### 从源码安装
180
+
181
+ ```sh
182
+ git clone <this-repository> dsh-CAIT
183
+ cd dsh-CAIT
184
+ npm run build:client
185
+ ```
186
+
187
+ 本地 `--patch` 覆盖层可以添加一行指向当前目录:
188
+
189
+ ```yaml
190
+ # _dev/cait.patch.yml
191
+ - insert:
192
+ - id: cait-dev
193
+ name: 'C:\absolute\path\to\dsh-CAIT'
194
+ ```
195
+
196
+ ```powershell
197
+ dsh web --patch C:\absolute\path\to\dsh-CAIT\_dev\cait.patch.yml
198
+ ```
199
+
200
+ `--patch` 是启动器选项;放在应用名(`web`)之后、应用自身参数之前。
201
+ 覆盖层和配置档中已安装的 bundle 二选一,不要同时使用。
202
+
203
+ ## 配置
204
+
205
+ | 选项 | 默认值 | 含义 |
206
+ | --- | --- | --- |
207
+ | `dataDir` | `""` | `store.json` 和 `sources/` 的目录。为空时使用 `$DSH_HOME/cait`。支持绝对路径、相对路径和 `~/...`。 |
208
+
209
+ ```yaml
210
+ - id: dsh-cait
211
+ name: dsh-cait
212
+ config:
213
+ dataDir: 'D:\CAT\cait-data'
214
+ ```
215
+
216
+ 快照保存文档、打开的标签页、TM、术语库、库、挂载关系和非敏感设置。
217
+ 导入的 DOCX/PPTX 源包放在 `sources/` 下。
218
+
219
+ 界面内的**设置**保存在快照里,而不是上面的 YAML:源语言/目标语言、模糊阈值、
220
+ TM 返回条数、MT 路由/模型/温度,以及界面语言(`uiLang`:`auto` | `zh` | `en` |
221
+ `ja`,默认 `auto` 即跟随 DSH 语言)。
222
+
223
+ 句段确认使用严格写入:如果快照无法写入,确认会以 `PERSISTENCE_FAILED`(503)
224
+ 失败,并回滚内存中的确认。其他结构性修改采用尽力写入,并通过工作台横幅显示
225
+ `bootstrap().storage.error`。
226
+
227
+ 如果快照损坏或版本未知,CAIT 会记录警告,将其移动到
228
+ `store.json.corrupt-<timestamp>`,然后以空状态启动,而不是让插件激活失败。
229
+ 版本 1 快照会迁移到版本 2,并创建默认 TM 和术语库。
230
+
231
+ ## Agent 工具
232
+
233
+ | 工具 | 用途 |
234
+ | --- | --- |
235
+ | `cat_get_segment` | 获取当前句段及 TM 匹配、术语命中 |
236
+ | `cat_submit_translation` | 确认译文,写入已挂载 TM(可选 `targetTmId`),前进到下一句 |
237
+ | `cat_lookup_tm` | 在已挂载库中按等级检索 TM |
238
+ | `cat_lookup_glossary` | 查询已挂载术语库;遵循 `caseSensitive` |
239
+ | `cat_list_documents` | 列出文档和进度 |
240
+ | `cat_switch_document` | 选择活动文档 |
241
+ | `cat_suggest_mt` | 通过所选 DSH 路由调用 MT,或使用明确的离线回退 |
242
+
243
+ 工作台和工具共用一个 `CatStore`,因此 Agent 可以翻译用户当前打开的同一份文档。
244
+
245
+ ## 架构
246
+
247
+ ```mermaid
248
+ flowchart LR
249
+ UI["DSH Web UI<br/>(侧栏 + 工作台)"] --> Client["client.js<br/>生成的 Web bundle"]
250
+ Client --> API["/cait/api/rpc<br/>同源 JSON"]
251
+ Tools["7 个 Agent 工具"] --> Store["CatStore"]
252
+ API --> Store
253
+ Store --> Snapshot[("store.json<br/>+ sources/")]
254
+ ```
255
+
256
+ - **Host**(`index.js`、`lib/`)负责存储、持久化、导入/导出、工具和私有 API。
257
+ - **Client**(`client/`)是通过 DSH 模块加载器加载的普通 React,渲染到
258
+ `sidebar.panellist` 和 `main`。样式只使用 `--dsw-alias-*` 令牌。
259
+ - `client.js` 是生成文件;请修改 `client/*.js`,然后运行 `npm run build:client`。
260
+
261
+ <details>
262
+ <summary><strong>项目结构</strong></summary>
263
+
264
+ ```text
265
+ cait/
266
+ ├─ package.json
267
+ ├─ cordis.patch.yml
268
+ ├─ index.js # Host 端
269
+ ├─ client.js # 生成的 Web bundle
270
+ ├─ client/ # helpers、styles、RPC、components、locales、entry
271
+ ├─ scripts/build-client.mjs
272
+ ├─ icon.svg
273
+ ├─ locale/{en,zh,ja}.json
274
+ ├─ NOTICE
275
+ ├─ README.md
276
+ ├─ README.zh-CN.md
277
+ ├─ README.ja.md
278
+ ├─ CHANGELOG.md
279
+ ├─ lib/
280
+ │ ├─ store.js # CatStore 门面 + 文档/句段核心
281
+ │ ├─ errors.js
282
+ │ ├─ store-utils.js
283
+ │ ├─ libraries.js # TM/术语库注册表 + 挂载
284
+ │ ├─ tm.js
285
+ │ ├─ glossary.js
286
+ │ ├─ persistence.js
287
+ │ ├─ import-export.js
288
+ │ ├─ formats.js # CSV/SRT/VTT/PO/XLIFF/HTML/JSON/RTF
289
+ │ ├─ xlsx.js
290
+ │ ├─ pptx.js
291
+ │ ├─ segmenter.js
292
+ │ ├─ similarity.js
293
+ │ ├─ tmx.js
294
+ │ ├─ docx.js
295
+ │ ├─ markdown.js
296
+ │ ├─ xml.js
297
+ │ ├─ mt.js
298
+ │ ├─ tools.js
299
+ │ └─ api.js
300
+ └─ _dev/ # 测试、fixture、本地 patch 覆盖层
301
+ ```
302
+
303
+ </details>
304
+
305
+ ## 开发
306
+
307
+ 需要 Node.js 22+ 和 DSH `0.2.x`。已在 DSH `0.2.2-rc.1`、Node `26.7.0`
308
+ 中测试。
309
+
310
+ ```sh
311
+ npm run build:client
312
+ node --check client.js
313
+
314
+ node _dev/test-core.mjs
315
+ node _dev/test-imports.mjs
316
+ node _dev/test-formats.mjs
317
+ node _dev/test-second-tier.mjs
318
+ node _dev/test-docx-export.mjs
319
+ node _dev/test-api.mjs
320
+ node _dev/test-plugin.mjs
321
+ node _dev/test-persistence.mjs
322
+ node _dev/test-documents.mjs
323
+ node _dev/test-libraries.mjs
324
+ node _dev/test-mounts.mjs
325
+ node _dev/test-ui-scale.mjs
326
+ node _dev/test-mt.mjs
327
+ ```
328
+
329
+ 导入/导出 fixture 为 `_dev/sample.docx`、`_dev/sample-table.docx` 和
330
+ `_dev/sample-format.docx`;可用对应的 `python _dev/make-*.py` 脚本重新生成。
331
+ 13 套测试应全部通过。
332
+
333
+ ### 发布
334
+
335
+ `npm publish` 会触发 `prepublishOnly`:从 `client/` 的片段重建 `client.js`
336
+ 并做语法检查,因此发布出去的不会是一个过期的 bundle。在仓库根目录执行:
337
+
338
+ ```sh
339
+ npm publish
340
+ ```
341
+
342
+ `.github/workflows/publish.yml` 会在 GitHub 发布 release 时做同样的事,使用
343
+ npm Trusted Publishing(OIDC)而不是保存的 token,并且当 release tag 与
344
+ `package.json` 的版本不一致时拒绝发布。
345
+
346
+ 首次发布必须在本地完成,因为 Trusted Publishing 只能为已经存在的包配置:
347
+
348
+ ```sh
349
+ npm login
350
+ npm publish
351
+ ```
352
+
353
+ 之后在 npmjs.com 打开该包,进入 **Settings → Trusted publishing**,添加仓库
354
+ `JoviLecca/dsh-CAIT` 和 workflow 文件 `publish.yml`。以后的版本就可以通过
355
+ GitHub release 发布。
356
+
357
+ ## 安全模型
358
+
359
+ - Host API 挂载在 `/cait/api`,通过 `ctx.connection.requestRejection`
360
+ 限制为同源/受信任请求。
361
+ - RPC 请求体为 JSON,上限 32 MB;超过时返回 `413 BODY_TOO_LARGE`。
362
+ - `clearTM` / `clearGlossary` 除了浏览器信任检查外,还要求
363
+ `params.confirm === true`;UI 会在发送前询问。
364
+ - CAIT 从不接收、存储或返回 API Key。DSH 凭据保留在所选提供方适配器内部。
365
+ - 持久化使用单个快照,语义为最后写入者获胜;它不是多用户日志。
366
+
367
+ ## 已知限制与路线图
368
+
369
+ - 暂不支持 PDF、EPUB 或图片 OCR 导入。
370
+ - DOCX 导入会跳过表格、页眉、脚注、域、替代文本和修订删除内容。
371
+ DOCX 导出时这些区域保持源语言。
372
+ - DOCX/PPTX 中混合 run 的段落会继承第一个 run 的格式。
373
+ - PPTX 导入只覆盖正文,不包含备注、图表或 SmartArt。
374
+ - XLSX 导入/导出是两列表格;不保留单元格样式、公式、合并单元格、图片和额外工作表。
375
+ - HTML/RTF 导出不往返原始样式;JSON 只翻译字符串值。
376
+ - TM 匹配是词法级的,不是语义级;没有词干、同义词或向量。
377
+ - 库重命名/删除和逐标签页挂载状态不属于 v1.0.0。
378
+ - 工作台界面提供中文、English、日本語三种语言,可在设置中切换;README 提供英文、简体中文和日文三个版本,以英文版为准。
379
+
380
+ 后续计划:PDF 与 EPUB 适配器、通过多模态 DSH 路由支持图片/视觉输入、
381
+ 更完整的库管理、保留样式的 XLSX 输出,以及 XLIFF `<alt-trans>` / 注释支持。
382
+
383
+ ## 变更日志与版本
384
+
385
+ 见 [CHANGELOG.md](CHANGELOG.md)。`v1.0.0` 是首个公开发布版本,`v1.0.1` 增加了
386
+ 日语界面和界面内语言切换,`v1.0.2` 让「跟随 DSH 语言」真正跟随 DSH 的语言设置,
387
+ `v1.0.3` 把包发布到 npm,`v1.0.4` 起后续版本改由带 provenance 的发布流水线产出;
388
+ 项目在开发阶段使用 `0.1.0`,发布到 GitHub 前统一改为 `1.0.0`。
389
+
390
+ > **License:** Apache License 2.0,见 [LICENSE](LICENSE)。再分发时需保留
391
+ > [NOTICE](NOTICE) 中的署名信息。